-
Notifications
You must be signed in to change notification settings - Fork 189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent replays of server data #78
Conversation
@riobard, answering your comment #77 (comment) here to keep it in context. Yeah, this new implementation has a separate filter for the server. I'm asking @bemasc to add a new error string to track that in the Prometheus metrics, so we'll be able to tell whether the attacker is actually using that. He decided to use a different approach:
Validation happens by repeating the operation and checking the tag. This way we don't need to rewire the code to get the cipher secret. |
@@ -259,7 +269,11 @@ func (s *tcpService) handleConnection(listenerPort int, clientConn onet.DuplexCo | |||
logger.Debugf("TCP Error: %v: %v", connError.Message, connError.Cause) | |||
status = connError.Status | |||
} | |||
s.m.AddClosedTCPConnection(clientLocation, keyID, status, proxyMetrics, timeToCipher, connDuration) | |||
var id string | |||
if cipherEntry != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this always true if keyErr is nil? This if is confusing me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is equivalent to if keyErr == nil
. This code runs whether keyErr
is nil or not. If it would be clearer, we could move this to line 234.
@fortuna I think the salt-size issue still applies here. Assuming you're using 32-byte salt and 28-byte random, that leaves 4 bytes for the tag. Not sure if it's sufficient. |
@riobard With a 4-byte tag, the false-positive rejection probability is one in 4 billion. That's much lower than the false positive rejection rate from our existing replay defense, so I think it's acceptable. |
@bemasc Ah, right! I forgot about the Bloom filter false positive rate :P Anyway, does Outline enforce 32-byte salt? |
The Outline Server only uses chacha20-ietf-poly1305, which has a 32-byte salt. I recommend against aes-128-gcm, and if someone is worried about a 12-byte salt, they can always migrate to the longer ciphers. |
This was caught by the presubmit in #78
In this version I added a check that disables the marking for this case, to be conservative. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! I like that you added the test. This looks really good. I only have a small suggestion for the case of a small salt, so we catch that early, output a warning, and keep the salt generator simpler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also add a section to the README explaining how the replay protection works? It can be short, but I'd like to have something I can point to other than the code. Cover both the client and server replays. Thanks!
@madeye You may be interested in this marked salt approach for shadowsocks-libev. It removes the need for saving server salts and can survive resets and old replays. |
Done. I put it in a separate file and linked it from the README. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! Thanks for suggesting and implementing the crypto salts. And I really like the document you added too. I'm looking forward to releasing this!
No description provided.