I have read everywhere that exposing personal
over rpc is dangerous and is vulnerable. The question is HOW?
Is it possible for anyone to send transactions to my geth console, if my ipaddress
and port on which geth is listening is compromised?
Secondly, I don't understand if it's a security threat, how are some coins based on Ethereum are able to provide their own wallet? They must be using RPC api to connect to geth. Isn't their coin at risk?
I am also building a web interface for my coin using web3.js
so that users of my coin could use web to access their accounts and carry out transactions but for that I need to expose personal
over RPC
. Am I compromising security? If yes, what else I can do to provide web access to my users of their accounts.
Can -rpcaddr
and -rpccorsdomain
help in any way? I couldn't understand their use properly. If I set --rpcaddr "ip1", "ip2" --rpccorsdomain "ip1"
, What does this means?
4 Answers
On the specific RPC questions:
--rpcaddr
is the address on which the user's geth rpc server would be listening. By default it's localhost. Localhost is normally only accessible to a process sending messages on the same computer, which is normally what you want. If you set this to a public IP address then anyone can connect to your node, which is very bad if the node controls your money and you've told it to let people spend it by sending it requests over the network.
If it's accepting requests on localhost, any process running locally can connect to it. However, your users trust all the processes running on their local computers, right? Well, maybe not. The first problem is that any other app can steal their money. But hopefully they didn't download any dodgy apps that will try to do this. But the second problem is, their browser is also running apps: Not just your app, but also the JavaScript of any other site the user is visiting.
Browsers try to handle this with a thing called the Same Origin Policy. This means that by default, you can only write JavaScript to access the same domain and the same port that you're using to view a page. Even this is a bit icky, because there are lots of ways that you can send data from browsers and not all of then are blocked, and this whole setup has quite a terrifyingly large attack surface. But people sometimes want to make exceptions to this policy, so there's a thing called Cross-Origin Resource Sharing (CORS), where a browser will ask a server, "other than yourself, are there any other domains+ports out there serving web pages that you want me to allow to talk to you?".
This is what Geth calls --rpccorsdomain
. If you want a browser to talk to geth and the browser is showing a page from a web server on localhost, you at least have to specify localhost plus the port that server is on. If you want to serve people the app from your domain, they have to tell their geth to let pages from your domain spend their money.
All of this is horrible. Yuck. Also, aargh.
Anyone who has the node's IP address and the port can use the RPC provider--there's no authentication. It's just plaintext HTTP. There's been at least one hack where an attacker got access through RPC to a node where the accounts were unlocked.
There is also the IPC provider, which is purely based on the filesystem. geth attach
, by default, uses the IPC, and by default the IPC has access to every API. You would likely have much better success working with IPC rather than trying to secure a RPC connection. Mist uses IPC, for example.
-
Thanks for the answer, but it does not address most of the points that I raised in my question Commented Sep 26, 2016 at 3:17
This kind of scenarios, where you use web3 interface to interact with Geth node, personal
is never exposed. Ideally geth
only exposes read-only APIs for untrusted client side JavaScript interaction.
Instead of this, you use the node just to broadcast the transaction to network. You do not use RPC APIs to built the transactions or interact with secrets (private keys).
All secrets are stored on the client side (window.localStorage
) or copy-pasted in by the users (copy paste hex private key to input field). Then web3 signs the transaction on client side and only pushes complete transactions through a node. Alternative, to send transactions, you can use push transactions services (example https://etherscan.io/pushTx )
-
Can you please answer second part of my question, too. How other coins build on ethereum are able to provide their web-wallet? They are sending transactions from web, I guess they must be using RPC to connect to geth. Commented Sep 30, 2016 at 5:55
-
My questions already answers to this. The transactions are signed on client side. Commented Sep 30, 2016 at 11:32
-
Sorry but I am unable to understand your point. Suppose I have launched my coin, How can I provide an interface(other than Mist) to users to access my token, make transactions etc. One solution I found was to use
RPC
. I wrote an HTML interface usingweb3
that works fine. But it has security concerns, like for letting users carry out transactions through thathttp interface
, I have to allowpersonal
over RPC, which is not recommended. SO what else are my options? Obviously other coins are doing it but HOW? Am I doing it all wrong? Commented Oct 1, 2016 at 6:17 -
Sorry for being unclear. Popular option includes e.g. MetaMask browser plugin that connect web3 to the user own wallet: chrome.google.com/webstore/detail/metamask/… Commented Oct 1, 2016 at 22:45
-
AFAIK MetaMask provides a WEB3 environment to browsers like Chrome. But for carrying out transactions using web3, I have to expose personal over RPC,which is not good. I am really confused at this point. How can I provide a web URL or something like that to access all functionalities of my coin and also security is not compromised. I have done the first part using RPC and web3, but I have exposed 'personal' over RPC to allow them to carry out transaction,which is a security concern Commented Oct 2, 2016 at 17:43
One simple trick could be host geth on separate server and only allow rpc over localhost. Then write a simple api on geth server which will receive requests from your other server, interact with geth and send you back the response. You can secure your api by adding some private key to the routes so that nobody can visit those api urls unless they know the key.
web-wallet
to users of my coin.