Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: 1.2
    • Fix Version/s: None
    • Component/s: HTTP Interface
    • Labels:
      None
    • Skill Level:
      New Contributors Level (Easy)

      Description

      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.

      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

        Activity

        Jason Smith created issue -
        Jason Smith made changes -
        Jason Smith made changes -
        Affects Version/s 1.2 [ 12315198 ]
        Affects Version/s 2.0 [ 12315572 ]
        Description 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
        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.

        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
        Benoit Chesneau made changes -
        Attachment 0001-handle-dropbox-db.-Add-dropbox-true-to-security-obje.patch [ 12504341 ]
        Benoit Chesneau made changes -
        Benoit Chesneau made changes -
        Attachment 0001-handle-dropbox-db.-Add-dropbox-true-to-security-obje.patch [ 12504341 ]
        Jason Smith made changes -
        Comment [ Hi, Benoit. No offense intended: as I re-read your patch I think you and I are making different features under the same name. The following Bash script clarifies my critique. I think you will agree that either (a) we are working on different things, with a name collision, "dropbox"; or (b) your patch is careless and dangerous.

        #!/bin/bash

        # Given: admin user "admin" and normal users "amy" and "bob"
        # New database
        curl -X DELETE http://admin:admin@localhost:5984/db
        curl -X PUT http://admin:admin@localhost:5984/db

        # Create a document
        curl -X PUT http://admin:admin@localhost:5984/db/doc1 -d '{"hello":"world"}'
        curl -X PUT http://admin:admin@localhost:5984/db/doc2 -d '{"hello":"world"}'

        # Amy is a member. Bob is not.
        curl -X PUT http://admin:admin@localhost:5984/db/_security -d '{"members":{"names":["amy"]}}'

        # Amy can open /db
        curl --fail http://amy:amy@localhost:5984/db

        # Bob cannot open /db
        curl --fail http://bob:bob@localhost:5984/db

        # Make a dropbox db
        curl -X PUT http://admin:admin@localhost:5984/db/_security -d '{"members":{"names":["amy"]}, "dropbox":true}'

        # Member amy cannot get a doc (regression)
        curl --fail http://amy:amy@localhost:5984/db/doc1

        # Non-member bob can get DB metadata (minor breach)
        curl --fail http://bob:bob@localhost:5984/db

        # Member amy cannot get _all_docs (regression)
        curl --fail http://amy:amy@localhost:5984/db/_all_docs

        # Non-member bob can fetch the entire database (major breach)
        curl --fail http://bob:bob@localhost:5984/db/_changes?include_docs=true

        # Anonymous users can fetch the entire database (major breach)
        curl --fail http://localhost:5984/db/_changes?include_docs=true ]
        Benoit Chesneau made changes -
        Benoit Chesneau made changes -

          People

          • Assignee:
            Unassigned
            Reporter:
            Jason Smith
          • Votes:
            9 Vote for this issue
            Watchers:
            11 Start watching this issue

            Dates

            • Created:
              Updated:

              Development