in3-server - key management  Pending
Secure and efficient key management is a challenge for any cryptographic system. Incubed nodes for example require an account on the ethereum blockchain to actively participate in the incubed network. The account and therefore a private-key is used to sign transactions on the ethereum blockchain and to provide signed proofs to other in3-nodes.\\nThis means that an attacker that is able to discover the keys used by an `in3-server` by any mechanism may be able to impersonate that node, steal the nodes funds or sign wrong data on behalf of the node which might also lead to a loss of funds.\\nThe private key for the `in3-server` can be specified in a configuration file called `config.json` residing in the program working dir. Settings from the `config.json` can be overridden via command-line options. The application keeps configuration parameters available internally in an `IN3RPCConfig` object and passes this object as an initialization parameter to other objects.\\nThe key can either be provided in plaintext as a hex-string starting with `0x` or within an ethereum keystore format compatible protected keystore file. Either way it is provided it will be held in plaintext in the object.\\nThe application accepts plaintext private keys and the keys are stored unprotected in the applications memory in JavaScript objects. The `in3-server` might even re-use the nodes private key which may weaken the security provided by the node. The repository leaks a series of presumably ‘test private keys' and the default config file already comes with a private key set that might be shared across unvary users that fail to override it.\\ncode/in3-server/config.json:L1-L4\\n```\\n{\\n  "privateKey": "0xc858a0f49ce12df65031ba0eb0b353abc74f93f8ccd43df9682fd2e2293a4db3",\\n  "rpcUrl": "http://rpc-kovan.slock.it"\\n}\\n```\\n\\ncode/in3-server/package.json:L20-L31\\nThe private key is also passed as arguments to other functions. In error cases these may leak the private key to log interfaces or remote log aggregation instances (sentry). See `txargs.privateKey` in the example below:\\ncode/in3-server/src/util/tx.ts:L100-L100\\n```\\nconst key = toBuffer(txargs.privateKey)\\n```\\n\\ncode/in3-server/src/util/tx.ts:L134-L140\\n```\\nconst txHash = await transport.handle(url, {\\n  jsonrpc: '2.0',\\n  id: idCount++,\\n  method: 'eth\\_sendRawTransaction',\\n  params: [toHex(tx.serialize())]\\n}).then((\\_: RPCResponse) => \\_.error ? Promise.reject(new SentryError('Error sending tx', 'tx\\_error', 'Error sending the tx ' + JSON.stringify(txargs) + ':' + JSON.stringify(\\_.error))) as any : \\_.result + '')\\n```\\n
Resolution\\nThe breakdown of the fixes addressed with git.slock.it/PR/13 are as follows:\\nKeys should never be stored or accepted in plaintext format Keys should only be accepted in an encrypted and protected format\\nThe private key in `code/in3-server/config.json` has been removed. The repository still contains private keys at least in the following locations:\\n`package.json`\\n`vscode/launch.json`\\n`example_docker-compose.yml`\\nNote that private keys indexed by a git repository can be restored from the repository history.\\nThe following statement has been provided to address this issue:\\nWe have removed all examples and usage of plain private keys and replaced them with json-keystore files. Also in the documentation we added warnings on how to deal with keys, especially with hints to the bash history or enviroment\\n\\nA single key should be used for only one purpose. Keys should not be shared.\\nThe following statement has been provided to address this issue:\\nThis is why we seperated the owner and signer-key. This way you can use a multisig to securly protect the owner-key. The signer-key is used to sign blocks (and convict) and is not able to do anything else (not even changing its own url)\\n\\nThe application should support developers in understanding where cryptographic keys are stored within the application as well as in which memory regions they might be accessible for other applications\\nAddressed by wrapping the private key in an object that stores the key in encrypted form and only decrypts it when signing. The key is cleared after usage. The IN3-server still allows raw private keys to be configured. A warning is printed if that is the case. The loaded raw private key is temporarily assigned to a local variable and not explicitly cleared by the method.\\nWhile we used to keep the unlocked key as part of the config, we have now removed the key from the config and store them in a special signer-function.\\nhttps://git.slock.it/in3/ts/in3-server/merge_requests/113\\n\\nKeys should be protected in memory and only decrypted for the duration of time they are actively used. Keys should not be stored with the applications source-code repository\\nsee previous remediation note.\\nAfter unlocking the signer key, we encrypt it again and keep it encrypted only decrypting it when signing. This way the raw private key only exist for a very short time in memory and will be filled with 0 right after. ( https://git.slock.it/in3/ts/in3-server/merge_requests/113/diffs#653b04fa41e35b55181776b9f14620b661cff64c_54_73 )\\n\\nUse standard libraries for cryptographic operations\\nThe following statement has been provided to address this issue\\nWe are using ethereumjs-libs.\\n\\nUse the system keystore and API to sign and avoid to store key material at all\\nThe following statement has been provided to address this issue\\nWe are looking into using different signer-apis, even supporting hardware-modules like HSMs. But this may happen in future releases.\\n\\nThe application should store the keys eth-address (util.getAddress()) instead of re-calculating it multiple times from the private key.\\nFixed by generating the address for a private key once and storing it in a private key wrapper object.\\n\\nDo not leak credentials and key material in debug-mode, to local log-output or external log aggregators.\\n`txArgs` still contains a field `privateKey` as outlined in the issue description. However, this `privateKey` now represents the wrapper object noted in a previous comment which only provides access to the ETH address generated from the raw private key.\\nThe following statement has been provided to address this issue:\\nsince the private key and the passphrase are actually deleted from the config, logoutputs or even debug will not be able to leak this information.\\nKeys should never be stored or accepted in plaintext format.\\nKeys should not be stored in plaintext on the file-system as they might easily be exposed to other users. Credentials on the file-system must be tightly restricted by access control.\\nKeys should not be provided as plaintext via environment variables as this might make them available to other processes sharing the same environment (child-processes, e.g. same shell session)\\nKeys should not be provided as plaintext via command-line arguments as they might persist in the shell's command history or might be available to privileged system accounts that can query other processes startup parameters.\\nKeys should only be accepted in an encrypted and protected format.\\nA single key should be used for only one purpose. Keys should not be shared.\\nThe use of the same key for two different cryptographic processes may weaken the security provided by one or both of the processes.\\nThe use of the same key for two different applications may weaken the security provided by one or both of the applications.\\nLimiting the use of a key limits the damage that could be done if the key is compromised.\\nNode owners keys should not be re-used as signer keys.\\nThe application should support developers in understanding where cryptographic keys are stored within the application as well as in which memory regions they might be accessible for other applications.\\nKeys should be protected in memory and only decrypted for the duration of time they are actively used.\\nKeys should not be stored with the applications source-code repository.\\nUse standard libraries for cryptographic operations.\\nUse the system keystore and API to sign and avoid to store key material at all.\\nThe application should store the keys eth-address (util.getAddress()) instead of re-calculating it multiple times from the private key.\\nDo not leak credentials and key material in debug-mode, to local log-output or external log aggregators.
```\\n{\\n  "privateKey": "0xc858a0f49ce12df65031ba0eb0b353abc74f93f8ccd43df9682fd2e2293a4db3",\\n  "rpcUrl": "http://rpc-kovan.slock.it"\\n}\\n```\\n