Skip to content

Instantly share code, notes, and snippets.

@sbisbee
Created February 8, 2011 23:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sbisbee/817490 to your computer and use it in GitHub Desktop.
Save sbisbee/817490 to your computer and use it in GitHub Desktop.
Proposal on how to prevent CSRF attacks against CouchDB with tokens.
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.
@varnerac
Copy link

varnerac commented Feb 1, 2014

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment