You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@couchdb.apache.org by "Jason Smith (JIRA)" <ji...@apache.org> on 2011/09/19 15:57:09 UTC

[jira] [Updated] (COUCHDB-1287) Inbox Database ("write-only" mode)

     [ https://issues.apache.org/jira/browse/COUCHDB-1287?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Jason Smith updated COUCHDB-1287:
---------------------------------

    Attachment: A_0003-Allow-non-member-writes-if-_security.members.allow_a.patch
                A_0002-Refactor-the-actual-read-check-out-of-the-member-che.patch
                A_0001-Refactor-reader_acl-test-functions-into-a-loop.patch

Proposed implementation attached.

## Notes

It would be nice to have _security.readers, _security.writers, and maybe sugar _security.members which implicitly populates both. A write-only DB would have _security.readers = {}, security.writers.roles = ["_anonymous"]. However this patch maintains compatibility with the 1.x codebase. (I tagged it v2.0 because v1.3 is not an option.)

The patch is not correct. Really, couch_db:open is an inappropriate place to assess authorization. Couch must know what the request will do before it determines authorization. It is unsafe to evaluate permission until execution enters the ultimate, true request handler. (Note that couch_db:check_is_admin/1 is sprinkled everywhere. Same deal.)

A more correct patch is more substantial; but substantial code changes is itself a security risk. I opted for the simpler way: whitelist a few good requests based on the method #httpd.path_parts. IMO, this implementation is fail-safe. Unexpected changes or execution isn't likely to grant access. (The couch_db:check_is_admin/1 stuff is fail-unsafe; we must remember to call it every time we change the code.)

> Inbox Database ("write-only" mode)
> ----------------------------------
>
>                 Key: COUCHDB-1287
>                 URL: https://issues.apache.org/jira/browse/COUCHDB-1287
>             Project: CouchDB
>          Issue Type: New Feature
>          Components: HTTP Interface
>    Affects Versions: 2.0
>            Reporter: Jason Smith
>            Priority: Minor
>         Attachments: A_0001-Refactor-reader_acl-test-functions-into-a-loop.patch, A_0002-Refactor-the-actual-read-check-out-of-the-member-che.patch, A_0003-Allow-non-member-writes-if-_security.members.allow_a.patch
>
>
> Currently, we can only grant combined read+write access in the _security object "members" section. A user can either do both or neither. This prevents a very common requirement for couch apps: sending private information from less-privileged users to more-privileged users.
> There is no (reasonable) way to make an "inbox" where anybody may create a doc for me, but only I may read it. An inbox database allows user-to-user, or user-to-admin private messages. (Not only chat messages, but asynchronous notifications--with a per-user inbox, perhaps even service requests and responses.)
> There is no reason _security.members (formerly .readers) should control write access. validate_doc_update() functions do this better.
> I propose a boolean flag, _security.members.allow_anonymous_writes. If it is true, then CouchDB will allow document updates from non-members, giving validate_doc_update() the final word on accepting or rejecting the update.
> Requirements:
> 1. Everything about _security stays the same (backward-compatible)
> 2. If members.allow_anonymous_writes === true, then most PUT and POSTs may proceed
> 3. All updates are still subject to approval by all validate_doc_update functions, same as before.
> The following unit tests cover as much of the functionality as I can think of. (My patch is unfinished but X indicates that I have it working.)
> X Set a database with validate_doc_update, members != []
> X member can write
> X non-member cannot read
> X non-member cannot write
> X non-member cannot write even with .is_ok = true
> X Set inbox mode
> For non-member:
>   X cannot update with .is_ok = false (still subject to validator)
>   X can create with .is_ok = true
>   X can update with .is_ok = true
>   X Can store an attachment with "_attachments"
>   X Can store attachments via direct query
>   X Can delete an attachment via direct query
>   X can delete the doc
>   X can create via an _update function
>   X can update via an _update function
>   * None of these should work:
>     X POST a temp view
>     X POST a view with {"keys":["keys", "which", "exist", "and some which don't"]
>     * POST /db/exist X-HTTP-Method-Override: GET
>     * POST /db/_all_docs
>     * POST /db/_changes
>     * For _show and _list:
>       * POST
>       * OPTIONS
>       * VARIOUS, NONSTANDARD, METHODS (in case Couch allows them later)
>   * These syntax/semantic errors in _security should all fail:
>     * .members.required_to_write = null, [missing], "", 0, true, 1, "false", [false], {false:false}
>     * .required_to_write = false
> These are the known changes to the security model. I consider these all to be either very unlikely in practice, or worth the trade-off.
> * If you write to an inbox DB, you know, for a time, a subset of its documents (but that's the point)
> * An _update function could reveal a document to the user, with or without changing it. However, an admin must install such a misguided update function.
> * You can launch timing attacks to learn information about validate_doc_update
>   * You might discover whether doc IDs exist in the DB or not
>   * You might discover a well-known open source validation function. You can look for bugs in its source code.
> * Zero or more things which Jason can't think of

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira