-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
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
Schannel: Failure when receiving data from the peer #4427
Comments
I tested using master. There has to be a known termination point otherwise an error will occur. (to be clear, close_notify is an acceptable termination point)
I walked through the code from the point of |
It looks like I confused myself, I have to walk that back there's no bug that I can see. In Wireshark while running curl w/openssl the close notify I see is sent by the client (libcurl), and curl w/schannel the encrypted alert is sent by the client (libcurl). In either case no alert is received (definitively with OpenSSL no close_notify is received before FIN; in schannel no encrypted alert is received before FIN therefore no close_notify is received). Therefore there is no known termination point. I have confirmed close_notify alerts work properly as a solo termination point when I test on other websites. I tested by doing this:
By ignoring content length here and telling the server to close the connection on a server that both sends content length and honors client close request we can simulate I've since tried your URL in Windows 7 8 10 and the result is the same. I've walked through the code again and watched all calls to DecryptMessage and it never returns SEC_I_CONTEXT_EXPIRED (close_notify received). Based on this I think it's a server issue, sorry for the confusion. |
Thanks for the debugging! Is there anything that can be done to make libcurl robust against such server behavior? |
libcurl is robust in handling missing HTTP response length. It will keep reading until TCP close if there is no found or allowed HTTP termination point. If the response is over SSL then libcurl must ensure the integrity which includes length. TCP close is not an acceptable indicator of length for the SSL layer because it may be manipulated by an attacker. As a last resort libcurl may treat the SSL layer termination point, aka close_notify alert, as an indicator of length. However, as you've seen on the contrary, other backends used by libcurl may treat TCP close as an indicator of length when the HTTP response is over SSL and no other termination point was given. That is for legacy reasons (like your server is 15 years old or misconfigured), is not robust, not healthy and I'm wholly against it. I hope one day it will be possible to fix it (starting in openssl.c) without breaking anything for anyone. Conceivably we could add a flag like CURLSSLOPT_ALLOW_TRUNCATION, CURLSSLOPT_ALLOW_ABRUPT_CLOSURE etc to allow the possibility of the attack similar to what we did for BEAST. At least with schannel I don't think it would see very much use since I can only recall few reports of this issue, despite Microsoft adding curl w/ schannel to Windows 10 at least a year? ago. |
Should we then move this to become a well phrased section in the TODO document instead? I don't think having this issue lingering open here will help us much. |
Yes that is fine by me. This problem appears is very rarerly and I don't understand it well enough to suggest a solution myself. |
I just ran across this issue today. We use schannel because we use an ssl inspection proxy. It was easier to enable schannel so git would use the windows cert store. Changing back to openssl and specifying the ca file manually resolved our issue as well. |
same issue here as well ... when downloading pacman tools for R source builds on WINdows |
I've found this same scenario happening.. we noticed that it happens to correlate with this message about HTTP 1.0 that shows only in scenarios it fails.. in scenarios it succeeds it uses HTTP 1.1:
We've also found that it only shows when repositories either grow large enough (20mb+ perhaps) or that they contain binary files.. (usually this coincides of course with size). So is it possible in some scenarios Libcurl negotiates down to HTTP 1.0 and subsequently the |
Not unless the app set CURLOPT_HTTP_VERSION to CURL_HTTP_VERSION_1_0. If you're only seeing it sometimes I think that's pretty unlikely.
You can use |
A user of the R bindings has reported a bug that happens in the schannel backend for this particular server:
Which does succceed in retrieving data, but in the end always errors like this:
This is with libcurl 7.64.1, haven't been able to test yet with 7.66. The problem does not appear when using the openssl backend.
The text was updated successfully, but these errors were encountered: