Skip to content
This repository has been archived by the owner on Oct 4, 2019. It is now read-only.

Commit

Permalink
Merge pull request #600 from ethereumproject/feat/unlock-rpc-warn
Browse files Browse the repository at this point in the history
log warning if unsafe use of RPC and account unlocking
  • Loading branch information
whilei authored Jun 1, 2018
2 parents 4851b12 + 52288ff commit a9c8b13
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 19 deletions.
3 changes: 3 additions & 0 deletions cmd/geth/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,9 @@ func logChainConfiguration(ctx *cli.Context, config *core.SufficientChainConfig)
glog.V(logger.Info).Infof("Using %d configured bootnodes", len(config.ParsedBootstrap))
glog.D(logger.Warn).Infof("Using %d configured bootnodes", len(config.ParsedBootstrap))
glog.V(logger.Info).Info(glog.Separator("-"))

// If unsafe usage, WARNING!
logIfUnsafeConfiguration(ctx)
}

// MustMakeChainConfigFromDefaults reads the chain configuration from hardcode.
Expand Down
86 changes: 86 additions & 0 deletions cmd/geth/log_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (

"github.com/ethereumproject/go-ethereum/logger"
"github.com/ethereumproject/go-ethereum/logger/glog"
"github.com/ethereumproject/go-ethereum/p2p/discover"
"net"
)

const defaultStatusLog = "sync=60s"
Expand Down Expand Up @@ -331,3 +333,87 @@ func logLoggingConfiguration(ctx *cli.Context) {
}

}

func logIfUnsafeConfiguration(ctx *cli.Context) {
// If RPC APIs include ANY of eth,personal,admin AND an account is unlocked, that's unsafe because
// anyone can use the unlocked account to sign and send transactions over the RPC API.
//
rpcapis := ctx.GlobalString(aliasableName(RPCApiFlag.Name, ctx))
unsafeRPCAPIs := []string{"eth", "personal", "admin"}
safeRPCListenAddrsWhitelist := [][2]net.IP{
discover.Ipv4ReservedRangeThis,
discover.Ipv4ReservedRangeLoopback,
discover.Ipv4ReservedRangePrivateNetwork,
discover.Ipv4ReservedRangeLocalPrivate2,
discover.Ipv6ReservedRangeLoopback,
}
stringContainsAny := func(s string, anyof []string) bool {
for _, ss := range anyof {
if strings.Contains(s, ss) {
return true
}
}
return false
}

possibleUnlockCondition := ctx.GlobalIsSet(UnlockedAccountFlag.Name) || ctx.GlobalIsSet(PasswordFileFlag.Name)
rpcEnabledCondition := ctx.GlobalBool(RPCEnabledFlag.Name)
rpcAPICondition := stringContainsAny(rpcapis, unsafeRPCAPIs)

// rpc listen addr is considered "safe", which is to be probably not exposed to the internet
rpcListenAddrCondition := func(configuredRPCListenAddr string) bool {
// listening on all interfaces, UNSAFE
if configuredRPCListenAddr == "*" {
return true
}
if strings.Contains(configuredRPCListenAddr, "localhost") {
return false
}
ip := net.ParseIP(configuredRPCListenAddr)
for _, n := range safeRPCListenAddrsWhitelist {
if ok, err := discover.IpBetween(n[0], n[1], ip); ok && err == nil {
return false
}
}
// parsed listen ip was NOT in the whitelist
return true
}(ctx.GlobalString(aliasableName(RPCListenAddrFlag.Name, ctx)))

unsafeCondition := possibleUnlockCondition && rpcEnabledCondition && rpcAPICondition && rpcListenAddrCondition

// check for EITHER --password or --unlock to be on the safe side, along with any of the sensitive RPC APIs enabled
if unsafeCondition {
func(vs []func(...interface{})) {
for _, v := range vs {
v(glog.Separator("-"))
v("*")
v(fmt.Sprintf(`
> !!! WARNING: Unsafe use of --%s and exposed RPC API [ currently: %s ]. !!!
>
> It's UNSAFE to unlock an account while exposing ANY of the following RPC APIs: %s to the internet.
> Anyone from the internet will be able to transfer funds from an unlocked account without any password.
>
> You can use the --%s flag to enable specific RPC API modules if necessary,
> and/or restrict the exposed RPC listen address with the --%s flag.
`,
UnlockedAccountFlag.Name,
rpcapis,
unsafeRPCAPIs,
aliasableName(RPCApiFlag.Name, ctx),
aliasableName(RPCListenAddrFlag.Name, ctx),
))
v("*")
v(glog.Separator("-"))
}
}([]func(...interface{}){
glog.V(logger.Warn).Warnln,
glog.D(logger.Warn).Warnln,
})
if !askForConfirmation("Do you really wish to proceed?") {
os.Exit(0)
}
}

}
38 changes: 19 additions & 19 deletions p2p/discover/udp.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,26 @@ var (
// I expect many of these occasions will be very unlikely.
//
// IPv4
ipv4ReservedRangeThis = [2]net.IP{net.ParseIP("0.0.0.0"), net.ParseIP("0.255.255.255")}
ipv4ReservedRangePrivateNetwork = [2]net.IP{net.ParseIP("10.0.0.0"), net.ParseIP("10.255.255.255")}
Ipv4ReservedRangeThis = [2]net.IP{net.ParseIP("0.0.0.0"), net.ParseIP("0.255.255.255")}
Ipv4ReservedRangePrivateNetwork = [2]net.IP{net.ParseIP("10.0.0.0"), net.ParseIP("10.255.255.255")}
ipv4ReservedRangeProviderSubscriber = [2]net.IP{net.ParseIP("100.64.0.0"), net.ParseIP("100.127.255.255")}
ipv4ReservedRangeLoopback = [2]net.IP{net.ParseIP("127.0.0.0"), net.ParseIP("127.255.255.255")}
ipv4ReservedRangeLinkLocal = [2]net.IP{net.ParseIP("169.254.0.0"), net.ParseIP("169.254.255.255")}
ipv4ReservedRangeLocalPrivate1 = [2]net.IP{net.ParseIP("172.16.0.0"), net.ParseIP("172.31.255.255")}
ipv4ReservedRangeSpecialPurpose = [2]net.IP{net.ParseIP("192.0.0.0"), net.ParseIP("192.0.0.255")}
ipv4ReservedRangeTestNet1 = [2]net.IP{net.ParseIP("192.0.2.0"), net.ParseIP("192.0.2.255")}
ipv4ReservedRange6to4 = [2]net.IP{net.ParseIP("192.88.99.0"), net.ParseIP("192.88.99.255")}
ipv4ReservedRangeLocalPrivate2 = [2]net.IP{net.ParseIP("192.168.0.0"), net.ParseIP("192.168.255.255")}
ipv4ReservedRangeSubnets = [2]net.IP{net.ParseIP("198.18.0.0"), net.ParseIP("198.19.255.255")}
ipv4ReservedRangeTestNet2 = [2]net.IP{net.ParseIP("198.51.100.0"), net.ParseIP("198.51.100.255")}
ipv4ReservedRangeTestNet3 = [2]net.IP{net.ParseIP("203.0.113.0"), net.ParseIP("203.0.113.255")}
ipv4ReservedRangeMulticast = [2]net.IP{net.ParseIP("224.0.0.0"), net.ParseIP("239.255.255.255")}
Ipv4ReservedRangeLoopback = [2]net.IP{net.ParseIP("127.0.0.0"), net.ParseIP("127.255.255.255")}
ipv4ReservedRangeLinkLocal = [2]net.IP{net.ParseIP("169.254.0.0"), net.ParseIP("169.254.255.255")}
ipv4ReservedRangeLocalPrivate1 = [2]net.IP{net.ParseIP("172.16.0.0"), net.ParseIP("172.31.255.255")}
ipv4ReservedRangeSpecialPurpose = [2]net.IP{net.ParseIP("192.0.0.0"), net.ParseIP("192.0.0.255")}
ipv4ReservedRangeTestNet1 = [2]net.IP{net.ParseIP("192.0.2.0"), net.ParseIP("192.0.2.255")}
ipv4ReservedRange6to4 = [2]net.IP{net.ParseIP("192.88.99.0"), net.ParseIP("192.88.99.255")}
Ipv4ReservedRangeLocalPrivate2 = [2]net.IP{net.ParseIP("192.168.0.0"), net.ParseIP("192.168.255.255")}
ipv4ReservedRangeSubnets = [2]net.IP{net.ParseIP("198.18.0.0"), net.ParseIP("198.19.255.255")}
ipv4ReservedRangeTestNet2 = [2]net.IP{net.ParseIP("198.51.100.0"), net.ParseIP("198.51.100.255")}
ipv4ReservedRangeTestNet3 = [2]net.IP{net.ParseIP("203.0.113.0"), net.ParseIP("203.0.113.255")}
ipv4ReservedRangeMulticast = [2]net.IP{net.ParseIP("224.0.0.0"), net.ParseIP("239.255.255.255")}
ipv4ReservedRangeFuture = [2]net.IP{net.ParseIP("240.0.0.0"), net.ParseIP("255.255.255.254")}
ipv4ReservedRangeLimitedBroadcast = [2]net.IP{net.ParseIP("255.255.255.255"), net.ParseIP("255.255.255.255")}

// IPv6
ipv6ReservedRangeUnspecified = [2]net.IP{net.ParseIP("::"), net.ParseIP("::")}
ipv6ReservedRangeLoopback = [2]net.IP{net.ParseIP("::1"), net.ParseIP("::1")}
Ipv6ReservedRangeLoopback = [2]net.IP{net.ParseIP("::1"), net.ParseIP("::1")}
ipv6ReservedRangeDocumentation = [2]net.IP{net.ParseIP("2001:db8::"), net.ParseIP("2001:db8:ffff:ffff:ffff:ffff:ffff:ffff")}
ipv6ReservedRange6to4 = [2]net.IP{net.ParseIP("2002::"), net.ParseIP("2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff")}
ipv6ReservedRangeUniqueLocal = [2]net.IP{net.ParseIP("fc00::"), net.ParseIP("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")}
Expand Down Expand Up @@ -750,24 +750,24 @@ func expired(ts uint64) bool {

func isReserved(ip net.IP) bool {
reserved := [][2]net.IP{
ipv4ReservedRangeThis,
ipv4ReservedRangePrivateNetwork,
Ipv4ReservedRangeThis,
Ipv4ReservedRangePrivateNetwork,
ipv4ReservedRangeProviderSubscriber,
ipv4ReservedRangeLoopback,
Ipv4ReservedRangeLoopback,
ipv4ReservedRangeLinkLocal,
ipv4ReservedRangeLocalPrivate1,
ipv4ReservedRangeSpecialPurpose,
ipv4ReservedRangeTestNet1,
ipv4ReservedRange6to4,
ipv4ReservedRangeLocalPrivate2,
Ipv4ReservedRangeLocalPrivate2,
ipv4ReservedRangeSubnets,
ipv4ReservedRangeTestNet2,
ipv4ReservedRangeTestNet3,
ipv4ReservedRangeMulticast,
ipv4ReservedRangeFuture,
ipv4ReservedRangeLimitedBroadcast,
ipv6ReservedRangeUnspecified,
ipv6ReservedRangeLoopback,
Ipv6ReservedRangeLoopback,
ipv6ReservedRangeDocumentation,
ipv6ReservedRange6to4,
ipv6ReservedRangeUniqueLocal,
Expand Down

0 comments on commit a9c8b13

Please sign in to comment.