-
-
Notifications
You must be signed in to change notification settings - Fork 30.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
Support Disabling Renegotiation for SSLContext #76438
Comments
Adding a new method in SSLContext so that we can disable renegotiation easier. |
Thanks for your patch, a few comments We generally don't have special functions to set flags. SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS is an OpenSSL < 1.1.0 option. OpenSSL 1.1.0 still defines the flag but no longer uses it. With your patch, the Python function would fail with a NameError. I don't think that self.options is the right way to set that flag. The option attribute manipulates SSL_CTX->options, which affects SSL->options. The flag has to be set on SSL->s3->flags. Your patch is missing documentation update and tests. |
I don't think your PR is required. The issue has been addressed in OpenSSL 0.9.8m over 7 years ago, https://access.redhat.com/security/cve/cve-2009-3555. From https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html
OpenSSL changelog Changes between 0.9.8l and 0.9.8m [25 Feb 2010] *) Implement RFC5746. Re-enable renegotiation but require the extension |
Hi Christian, Thank you for review! I have changed the code to directly setting this flag by using s3->flag. Code is copied from nginx repo: https://github.com/nginx/nginx/blob/ed0cc4d52308b75ab217724392994e6828af4fda/src/event/ngx_event_openssl.c. I think this change is still needed. Although OpenSSL claimed it is fixed, THC-SSL-DOS showed it is vulnerable. If this is not the case, then nginx won't need to set the flag. Thanks, |
If it's a bug in OpenSSL, please report the bug with OpenSSL and request a fix. Bugs should be patched where they occur. Can you contact OpenSSL development team, please? The flag is not documented and I don't know how it influences OpenSSL. Does the flag only affect SSL 3.0 or also TLS 1.0 and newer? |
I don't think it is a bug in OpenSSL. For various reasons, certain applications must allow renegotiation while this leaves security problem for others. That's why if python can control this flag, applications will be more confident in dealing with DoS attacks aimed at renegotiation. This flag controls not only SSL3 but also TLSv1.1 and TLSv1.2 after testing on Nginx and Gevent. As of OpenSSL 1.0.2h, in file ssl/s3_lib.c int ssl3_renegotiate(SSL *s)
{
if (s->handshake_func == NULL)
return (1);
s->s3->renegotiate = 1;
return (1);
} |
Another reason to consider making it possible to disable renegotiation is HTTP/2. RFC 7540 says: A deployment of HTTP/2 over TLS 1.2 MUST disable renegotiation. An |
Sounds about right, but I cannot find a good way to disable renegotiation.
|
Apache mod_ssl implements CVE-2009-3555 by carefully tracking renegotiation state through-out the code base and a custom IO layer that refuses IO when the reneg_state becomes invalid. [1] https://github.com/apache/httpd/blob/trunk/modules/ssl/ssl_private.h#L502-L513 |
Thank you for the investigation. This does seem better than the flag. Shall we go ahead implement this? |
There must be a better way than custom BIOs. An implemented based on Apache's approach is probably > 1,000 lines of C code and a massive compliciation of the module. |
How about exposing the internal ssl object? This will allow applications to control the flag. |
It looks like openssl master has SSL_OP_NO_RENEGOTIATION: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html Before that, I guess one could use SSL_CTX_sess_{connect,accept}_renegotiate to detect when a renegotiation has occurred and then error out? Admittedly this is more effective in nonblocking or memorybio mode. Or you could do something similar with the info callback: allow the current operation to succeed, but mark the connection as "poisoned". (Heck, in socket bio mode you could flat out close the socket. That'll shut things down.) For bonus annoyance, note that RFC 7240 does allow implementations to support renegotiation that happens before any data is exchanged, to allow for the encrypted client cert hack. |
Thanks for checking! I had only checked 1.0.2 and 1.1.0 branch... I can easily expose the info cb in Python -- but there is no simple way to bubble up an exception from a callback to Python. The server name callback ignores exception and just prints them with PyErr_WriteUnraisable(). Since OpenSSL 1.1.1 will have SSL_OP_NO_RENEGOTIATION, I'm leaning towards not making the code more complicated. Either we have to wait for 1.1.1 or ask OpenSSL to backport the feature to 1.0.2 and 1.1.0. |
I took Guido's keys to the time machine: openssl/openssl#4739 |
Thanks Christian! Let's wait for OpenSSL then. |
We don't work that way. Closed means closed forever. Please leave the bug open. |
The OP_NO_RENEGOTIATION option prevents renegotiation in TLS 1.2 and lower. Renegotiation is a problematic TLS feature that has led to security issues like CVE-2009-3555. TLS 1.3 has removed renegotiation completely in favor of much more reliable and simpler rekeying. PR5904 just adds the constant to the list of options and documents it. I didn't add it earlier because it wasn't available in the OpenSSL 1.1.0 branch until now. The next upcoming release of 1.1.0 will have it. |
Thanks, Christian! Merged for 3.7.0 and 3.8.0. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: