reconsider update-write-enabler plan, allows an attack #489
Labels
No Label
0.2.0
0.3.0
0.4.0
0.5.0
0.5.1
0.6.0
0.6.1
0.7.0
0.8.0
0.9.0
1.0.0
1.1.0
1.10.0
1.10.1
1.10.2
1.10a2
1.11.0
1.12.0
1.12.1
1.13.0
1.14.0
1.15.0
1.15.1
1.2.0
1.3.0
1.4.1
1.5.0
1.6.0
1.6.1
1.7.0
1.7.1
1.7β
1.8.0
1.8.1
1.8.2
1.8.3
1.8β
1.9.0
1.9.0-s3branch
1.9.0a1
1.9.0a2
1.9.0b1
1.9.1
1.9.2
1.9.2a1
LeastAuthority.com automation
blocker
cannot reproduce
cloud-branch
code
code-dirnodes
code-encoding
code-frontend
code-frontend-cli
code-frontend-ftp-sftp
code-frontend-magic-folder
code-frontend-web
code-mutable
code-network
code-nodeadmin
code-peerselection
code-storage
contrib
critical
defect
dev-infrastructure
documentation
duplicate
enhancement
fixed
invalid
major
minor
n/a
normal
operational
packaging
somebody else's problem
supercritical
task
trivial
unknown
was already fixed
website
wontfix
worksforme
No Milestone
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Reference: tahoe-lafs/trac-2024-07-25#489
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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.
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.
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.
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.
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.