I wrote
secure programming notes for CouchDB applications. This is written in Japanese, so I've started the translation into English.
--
The first topic is about "View protection" in CouchDB.
For example, we prepare the view as follows.
function(doc){
emit([doc.owner, doc.created_at], doc.protected);
}
The result of this view will be as follows.
{ "total_rows": 1234, "offset", 0, "rows": [
{"id" : "...", "key": ["user1", "2009/01/01"], value: {...}},
{"id" : "...", "key": ["user1", "2009/01/01"], value: {...}},
{"id" : "...", "key": ["user1", "2009/01/02"], value: {...}},
{"id" : "...", "key": ["user2", "2009/01/02"], value: {...}},
{"id" : "...", "key": ["user2", "2009/01/02"], value: {...}},
...
]}
If we have a security requirment that only document owner can view the doc.protected field, this view should be handled carefully. The current CouchDB view implemetation has no authentication function so that authorization function cannot be implemented.
So how do we solve this requirement?
The answer is:
- to use a reverse proxy to forbid direct view access.
- to use _list functions for view result processing.
And we need to check parameters in our list function.
function(head, req){
// !code vendor/json/json2.js
var startkey = JSON.parse(req.query.startkey || "[]");
var endkey = JSON.parse(req.query.endkey || "[]");
if(startkey[0] == endkey[0] &&
startkey[0] == req.userCtx.name ){
while(row == getRow()){
// row.key[0] == req.userCtx.name is always true.
}
}else{
// not authorized
}
}