[DRAFT] [Workbench] Prevent CSRF and XSS attacks
A CSRF or XSS attack could enable an attacker to obtain or use secret tokens.
Right now, after log in, the token gets stored in the Rails4 session cookie.XSS: Attacker inserts a
<script>tag in content that gets rendered on the same page as the CSRF token and API token. That script can read the tokens from the DOM, use the tokens to make API requests, and send the tokens to a server of the attacker's choice.
- The script does not need to decrypt the session in order to make authenticated Workbench requests.
- The page does currently provide the unencrypted API token in a
metaelement, as a way to enable the Workbench client code to make API (REST and websocket) and Keep requests. (The crux here seems to be: it should be possible for Workbench's own scripts to make arbitrary API/keepproxy requests, but impossible for a malicious script injected in a Workbench page to do the same thing.)
- Rails provides some CSRF protection using its own token system.
- API server does not use session cookies for most routes (but it does use them during login).
- Other services (keepstore, keepproxy) do not use session cookies at all.
#8 Updated by Tom Clegg over 4 years ago
- Subject changed from [API] Potential CSRF vulnerability to [Workbench] Prevent CSRF and XSS attacks
- Description updated (diff)
(moved out of story description)Proposed alternative to providing the API token in a
- If we want to send the encrypted Rails 4 session to API server, we may be able to provide a custom session Rack layer that handles Rails 4 sessions for our Rails 3 site: https://stackoverflow.com/questions/1941499/given-the-session-key-and-secret-how-can-we-decrypt-rails-cookies
- To send to keepproxy, we can decrypt it in Go: http://big-elephants.com/2014-01/handling-rails-4-sessions-with-go/
- This requires the Rails
secret_tokenbe shared between Workbench, API and keepproxy
Preferably we don't have to share the whole session, but use some other header instead that has the encrypted API token. This still requires a shared secret between services. We also need to generate and verify the encrypted token in such a way that it can't be trivially re-used in a replay attack.
(But [how] can an encryption layer make it impossible for a malicious embedded script to make use of the token, without also making it impossible for Workbench's own scripts to use it? -TC)