Created
February 8, 2011 23:04
-
-
Save sbisbee/817490 to your computer and use it in GitHub Desktop.
Proposal on how to prevent CSRF attacks against CouchDB with tokens.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Proposal to Prevent CSRF Attacks on CouchDB with Tokens | |
======================================================= | |
This is a draft for commentary from the community. | |
Goals | |
----- | |
1. Establish a mechanism that would defeat CSRF attacks against CouchDB by | |
leveraging the standard provided by OWASP at | |
http://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet | |
2. The mechanism should be easily abstracted into a library that's used to | |
connect to CouchDB so that application developers do not need to worry about | |
it. | |
3. The mechanism must be able to be turned off, allowing for backward | |
compatibility. | |
4. The architecture of the mechanism must take into account web browsers, | |
single node and multi-node CouchDB systems (2 nodes up to clusters), and | |
multiple clients utilizing the same authentication credentials. | |
5. Ideally the mechanism would be simple to implement (see: relax). | |
Definitions | |
----------- | |
'Write request' An HTTP POST, PUT, COPY, or DELETE request to the CouchDB | |
server. | |
'CSRF Token' A string that is required by the server when the client | |
attempts to send a write request. | |
Overview | |
-------- | |
Every write request sent to CouchDB with authentication information will | |
require a CSRF token in the query string. Using the query string allows clients | |
that do not have access to the HTTP headers to still make requests. | |
The next expected CSRF token for the current session will be returned to the | |
client when it makes any valid request. It will only be regenerated when the | |
client makes a valid write request with the CSRF token. | |
If an invalid or unexpected token is sent, then an HTTP 401 response will be | |
sent regardless of whether the authorization credentials were correct or not, | |
or whether CSRF is required or not. | |
CSRF Token Format | |
----------------- | |
Tokens are a 5 character randomly generated alphanumeric string. Their | |
generation does not rely on any session or user based resources (ex., session | |
IDs, user IDs, system time, and other guessable data). | |
Storage Mechanisms | |
------------------ | |
The two options will be (1) in memory, utilizing a cache of a set size, and (2) | |
in _local, which will persist to the disk but cannot be replicated. Memory | |
would be the preferred option if replication is not needed, and therefore the | |
default setting. | |
The following information needs to be hashed together and stored: user name, | |
session key, and CSRF token. Including the session key allows multiple clients | |
to connect to CouchDB at the same time from multiple clients (ex., multiple | |
PCs, servers, and mobile devices). | |
The session TTL would be reused to clear items from the cache. | |
Configuration | |
------------- | |
This token requirement may be turned off to allow backward compatibility. | |
However, there should be a stern warning against this. The default will be to | |
have it enabled. | |
The storage mechanism (memory vs. _local) may be selected as well. The default | |
will be memory, as it is more performant and will not impact disk consumption. | |
Storage mechanism size may also be configured. | |
Discussion: Impact on Clients | |
----------------------------- | |
Client libraries will need to remember the last CSRF token that was sent, which | |
is reasonable as they already have to remember authentication information. | |
Before the client makes an authenticated write request, it will need to make a | |
GET request and store the returned CSRF token. Ideally it would make the | |
request to a resource that doesn't return much data (ex., the server's root | |
path). | |
Discussion: Impact on Multi-Node Systems | |
---------------------------------------- | |
There are three viable solutions: | |
1. Provide an API that cluster implementors could hook into, providing their | |
own method of supporting secure sessions. | |
2. Use sticky sessions to ensure the client connects to the node that has their | |
session and CSRF token. Any storage mechanism can be used. | |
3. Larger multi-node systems may want to use a shared resource or store the | |
CSRF and session data in the gateway. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Why would you store user name and session info about the key? It seems like there would two scenarios. First, for session based access, you'd only store the session. Second, for basic authentication and no session, you'd only store the user name. In the case of basic authentication only, you'd also create and store a TTL.