mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
console: improve web3ext loader
The old one worked, but evaluating JS code created from server-provided input is weird and can lead to RCE in case the console is used with a malicious server.
This commit is contained in:
parent
3ee39f28d1
commit
832d1100b9
1 changed files with 34 additions and 24 deletions
|
|
@ -116,30 +116,8 @@ func (c *Console) init(preload []string) error {
|
||||||
if err := c.initWeb3(bridge); err != nil {
|
if err := c.initWeb3(bridge); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := c.initExtensions(); err != nil {
|
||||||
// Load the supported APIs.
|
return err
|
||||||
apis, err := c.client.SupportedModules()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("api modules: %v", err)
|
|
||||||
}
|
|
||||||
flatten := "var eth = web3.eth; var personal = web3.personal; "
|
|
||||||
for api := range apis {
|
|
||||||
if api == "web3" {
|
|
||||||
continue // manually mapped or ignore
|
|
||||||
}
|
|
||||||
if file, ok := web3ext.Modules[api]; ok {
|
|
||||||
// Load our extension for the module.
|
|
||||||
if err = c.jsre.Compile(fmt.Sprintf("%s.js", api), file); err != nil {
|
|
||||||
return fmt.Errorf("%s.js: %v", api, err)
|
|
||||||
}
|
|
||||||
flatten += fmt.Sprintf("var %s = web3.%s; ", api, api)
|
|
||||||
} else if _, err := c.jsre.Run("web3." + api); err == nil {
|
|
||||||
// Enable web3.js built-in extension if available.
|
|
||||||
flatten += fmt.Sprintf("var %s = web3.%s; ", api, api)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if _, err = c.jsre.Run(flatten); err != nil {
|
|
||||||
return fmt.Errorf("namespace flattening: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add bridge overrides for web3.js functionality.
|
// Add bridge overrides for web3.js functionality.
|
||||||
|
|
@ -204,6 +182,38 @@ func (c *Console) initWeb3(bridge *bridge) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initExtensions loads and registers web3.js extensions.
|
||||||
|
func (c *Console) initExtensions() error {
|
||||||
|
// Compute aliases from server-provided modules.
|
||||||
|
apis, err := c.client.SupportedModules()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("api modules: %v", err)
|
||||||
|
}
|
||||||
|
aliases := map[string]struct{}{"eth": {}, "personal": {}}
|
||||||
|
for api := range apis {
|
||||||
|
if api == "web3" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
aliases[api] = struct{}{}
|
||||||
|
if file, ok := web3ext.Modules[api]; ok {
|
||||||
|
if err = c.jsre.Compile(api+".js", file); err != nil {
|
||||||
|
return fmt.Errorf("%s.js: %v", api, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply aliases.
|
||||||
|
c.jsre.Do(func(vm *goja.Runtime) {
|
||||||
|
web3 := getObject(vm, "web3")
|
||||||
|
for name, _ := range aliases {
|
||||||
|
if v := web3.Get(name); v != nil {
|
||||||
|
vm.Set(name, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// initAdmin creates additional admin APIs implemented by the bridge.
|
// initAdmin creates additional admin APIs implemented by the bridge.
|
||||||
func (c *Console) initAdmin(vm *goja.Runtime, bridge *bridge) {
|
func (c *Console) initAdmin(vm *goja.Runtime, bridge *bridge) {
|
||||||
if admin := getObject(vm, "admin"); admin != nil {
|
if admin := getObject(vm, "admin"); admin != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue