Opened at 2008-07-17T19:46:33Z
Closed at 2011-07-21T19:50:28Z
#489 closed defect (invalid)
reconsider update-write-enabler plan, allows an attack
Reported by: | warner | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | undecided |
Component: | code-mutable | Version: | 1.1.0 |
Keywords: | newcaps security | Cc: | |
Launchpad Bug: |
Description
I've been planning to allow clients to respond to a BadWriteEnablerError by assuming the share they're dealing with was migrated from one server to another, and then use the new update_write_enabler() method to fix the write-enabler.
But thinking about it further, this allows a malicious server to use the client as an oracle that will tell it all the write-enablers it wants. It just needs to emit a bogus BadWriteEnablerError with the serverid of its choosing. The client will then attempt to update it by sending both old-enabler and new-enabler. This tells the server what the old-enabler was, i.e. what the write-enabler for the other server is. By repeating this several times, the server can obtain the write-enabler for everything.
This suggests a fix: the update_write_enabler method should accept the hash of the old-enabler, rather than the old-enabler itself.
This needs some more thought.. I don't *think* this gives the malicious server any new authority. Specifically, will server2 accept an update request with the string that server1 was just given? Could the malicious server use this to get enough authority (i.e. hashes of write-enablers) to allow it to convince other servers to update their write-enablers? It might also require a check that prevents update-write-enabler from replacing a write-enabler that is for the current serverid.
Change History (4)
comment:1 Changed at 2008-07-17T19:51:34Z by warner
comment:2 Changed at 2008-07-22T00:37:24Z by warner
I'm going to remove the update_write_enabler method from the codebase before we release v1.2.0, so it won't be cluttered with an unhelpful method.
I think I've got a scheme drawn up to do this safely, which will use a different method signature. Assume the share was migrated from A to B, so it contains WE.A and we want to update it to have WE.B . Server B reports a bad-write-enabler error to the client and mentions that the share has a write enabler for A. The client computes WE.A as usual, then sends:
(H(B+WE.A), WE.B)
The server computes H(my_serverid+old_WE) and compares it against the client's value. If they match, it modifies the share to include the new WE.B .
The client's message is only useful when sent to server B, since no other server will compute a hash using "B" as the second value. If evil server B tries to use the client to obtain, say, WE.C (by pretending that the share was migrated from server C instead of server A), the client will compute H(B+WE.C) and give it to B. B has no way to compute H(C+WE.C), since it never learns WE.C, so there's nothing that B can use to convince C to update a write-enabler.
This needs a bit of review first.
Of course, we can't actually migrate mutable shares until all servers implement this method, and all clients whose shares are affected have the corresponding client-side code to call it in response to errors.
comment:3 Changed at 2009-10-28T04:17:01Z by davidsarah
- Keywords newcaps security added
Tagging issues relevant to new cap protocol design.
I think we want to avoid using write enablers in the new design if possible, which would obviate the problem in this ticket.
comment:4 Changed at 2011-07-21T19:50:28Z by davidsarah
- Resolution set to invalid
- Status changed from new to closed
If we support updating write-enablers then we will probably do so using the protocol invented at the first Tahoe-LAFS summit, described in #1426, which is not subject to the attack described here.
Another approach would be to make the update-write-enabler call require a signed message, and have it verify the signature against the pubkey inside the share. I've been reluctant to require the storage server to know very much about the layout of the share: doing that will cause update problems in the future, since we'll need to upgrade all the storage servers when we want to change the share layout on the client side. But it may be necessary.
Storage APIs that require signature checking will be more expensive than those that use shared secrets. But a repair/update call like this won't happen too frequently. I'm hopeful that the regular writev call can avoid pubkey operations, but I'm ok with repair requiring it.
If we do this, the signed message should include the serverid to which the message is intended, to prevent server1 from using it against server2.