steemit / condenser

The greatest application front-end to the Steem Blockchain.
https://steemit.com
505 stars 429 forks source link

Secure server login session [proposal] #518

Closed jcalfee closed 7 years ago

jcalfee commented 8 years ago

This proposal allows a user to prove to the server that they have access to one or more private keys in their account's blockchain authority record. The session may be easily tested on any server in a cluster and used to make decisions about access to API resources.

This is a bit involved but is very standard stuff. It uses standard familiar routines and so the implementation should be efficient. Allow for at least two days for this to become implemented and stable.

Summary

User logs in to the web client and the login proceeds as normal. Upon success the client reports the login event to the server as normal. At this point the server would have established a secure session which includes a unique session nonce both in the encrypted session and in the plain text session. The client may then look for the unencrypted nonce and sign this nonce along with their username and role to prove to the server they have a private key. This information and signature is sent to the server and the server verifies it and records the result in a secure server cookie. The client then passes this cookie to any server in the cluster it contacts.

Secure Server Sessions

The implementation is an extension to koa (our existing web framework) and involves about 60 lines of code. This implementation exists already. One change is needed. Given this is such a small stable library forking it does not pose any significant drawbacks. The change is to add a unique nonce (the time + random value) for the IV value to prevent IV value re-use.

This entire implementation for the secure session is in index.js. Here are the encrypt and decrypt routines: https://github.com/koa-modules/koa-crypto-session/blob/35a9e826d550d69b7465c68dbd4d4fdb22102fc8/index.js#L26-L40

This is the one change needed to avoid re-using the IV (initialization vector) value to improve security:

https://github.com/koa-modules/koa-crypto-session/issues/3

Token Signing

server_unique_nonce=String(Date.now() + random_global_const) role=posting, active, owner, memo username=blockchain account name

// stringify creates a consistent JSON string with no indenting and no extraneous spaces sign_text=JSON.stringify({server_unique_nonce, role, username}, null, 0)

When logging in, the client can construct and sign sha256(sign_text) with the key corresponding to the given role. The server can then verify it by pulling the blockchain public key for the given user and role and (if passed) use koa-crypto-session to store the users status: this.secure_session['auth_${username}_${role}'] = true ..

Config

A STEEMIT_SECRET=xxx will be added to the server's config file. This will be a 256 bit base64 encoded random value. The same random value may be used cluster wide to enable any server in the cluster to read and modify the user's session. The sha256(${STEEMIT_SECRET} koa-crypto-session) is the key for koa-crypto-session.

A new session key will be used and will not interfere with the existing unencrypted koa session like the one used in account signups.

Logout

The client deletes the server's secure cookie. Any additional API calls will not verify. Currently the websocket does not use this secure session so a remote API call upon logout should not be needed.

jcalfee commented 8 years ago

Fyi, cookie size limits (per domain) are typically 4k for all cookies on the entire domain. http://browsercookielimits.squawky.net/

jcalfee commented 8 years ago

Adding an additional session https://github.com/koajs/session/issues/62

jcalfee commented 8 years ago

After login, the server can see if the user is logged in.

const hasPostingAuthority = this.session.auth && this.session.auth.posting

Active authority (this.session.auth.active) is not necessarily set unless the login took place on a wallet or market page with an active key.

sneak commented 8 years ago

@jcalfee i would like to review this from a security standpoint before we ship it, and perhaps even have an external set of eyeballs on the security assumptions.

valzav commented 8 years ago

Let's have it out sooner - I need this functionality for the in-app notifications.