-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Fix #21760 - Close Tls connection if Inbound closed before receiving peer's close_notify (v.2) #21786
Conversation
…ing peer's close_notify When application closes inboud using engine.closeInbound the engine can generate an alert message and put it into writer.outboundList. As a result the engine can have a new data packet in outbound and its isOutboundDone will be false. We have to ensure that it will be flushed to the network, that's why we have to update lastHandshakeStatus via the actual status of the engine. Otherwise the actor will transition to the flushingOutbound state but will never flush outbound, since engineNeedsWrap precondition will be false. Generally speaking whenever we signal something to the SSLEngine, weshould also read getHandshakeStatus afterwards to understand what we need to do next. This was done everywhere but for this engine.closeInbound.
Can one of the repo owners verify this patch? |
OK TO TEST |
Thanks for the excellent research + writeup and fix. |
Test FAILed. |
Does not look like the failed test is related to this commit. |
PLS BUILD |
Test PASSed. |
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.
LGTM, I vote for this one.
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.
LGTM
}) | ||
.runWith(Sink.last) | ||
|
||
Await.result(f, 8.second).utf8String should be(scenario.output.utf8String) |
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 test!
@@ -292,6 +292,7 @@ class TLSActor( | |||
if (tracing) log.debug("closing inbound") | |||
try engine.closeInbound() | |||
catch { case ex: SSLException ⇒ outputBunch.enqueue(UserOut, SessionTruncated) } | |||
lastHandshakeStatus = engine.getHandshakeStatus |
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.
ah, so this needs to be updated here. Thanks!
Enough LGTMs I believe :) |
…ing peer's close_notify (akka#21786) When application closes inboud using engine.closeInbound the engine can generate an alert message and put it into writer.outboundList. As a result the engine can have a new data packet in outbound and its isOutboundDone will be false. We have to ensure that it will be flushed to the network, that's why we have to update lastHandshakeStatus via the actual status of the engine. Otherwise the actor will transition to the flushingOutbound state but will never flush outbound, since engineNeedsWrap precondition will be false. Generally speaking whenever we signal something to the SSLEngine, weshould also read getHandshakeStatus afterwards to understand what we need to do next. This was done everywhere but for this engine.closeInbound.
…cenario That is we are simulating a TLS truncation attack here. Before akka/akka#21786 the TLS stage just got stuck (I tested again an old Akka version). Now, all streams are properly closed and also the response entity stream is completed. A stricter version would actually fail the response entity stream when TLS truncation is detected. If that is worthwhile is actually questionable. See akka#235 for more information.
…cenario That is we are simulating a TLS truncation attack here. Before akka/akka#21786 the TLS stage just got stuck (I tested again an old Akka version). Now, all streams are properly closed and also the response entity stream is completed. A stricter version would actually fail the response entity stream when TLS truncation is detected. If that is worthwhile is actually questionable. See akka#235 for more information.
Fixes #21760
Also fixes akka/akka-http#380 and probably akka/akka-http#87
This is a second variant of testing the fix (an alternative is #21785)
Initial discussion is in #21761
When application closes inboud using engine.closeInbound the engine can generate an alert message and put it into writer.outboundList. As a result the engine can have a new data packet in outbound and its isOutboundDone will be false. We have to ensure that it will be flushed to the network, that's why we have to update lastHandshakeStatus via the actual status of the engine. Otherwise the actor will transition to the flushingOutbound state but will never flush outbound, since engineNeedsWrap precondition will be false.
Generally speaking whenever we signal something to the SSLEngine, weshould also read getHandshakeStatus afterwards to understand what we need to do next. This was done everywhere but for this engine.closeInbound.