mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
Further mitigation for the TLS renegotation attack, CVE-2009-3555:
* modules/ssl/ssl_engine_kernel.c (has_buffered_data): New function. (ssl_hook_Access): Forcibly disable keepalive for the connection if there is any buffered data readable from the input filter stack. * modules/ssl/ssl_engine_io.c (ssl_io_filter_input): Ensure that the BIO uses blocking operations when invoked outside direct control of the httpd filter stack. Thanks to Hartmut Keil <Hartmut.Keil adnovum.ch> for proposing this technique. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@891282 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -1344,9 +1344,17 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* We have no idea what you are talking about, so return an error. */
|
/* We have no idea what you are talking about, so return an error. */
|
||||||
return APR_ENOTIMPL;
|
status = APR_ENOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* It is possible for mod_ssl's BIO to be used outside of the
|
||||||
|
* direct control of mod_ssl's input or output filter -- notably,
|
||||||
|
* when mod_ssl initiates a renegotiation. Switching the BIO mode
|
||||||
|
* back to "blocking" here ensures such operations don't fail with
|
||||||
|
* SSL_ERROR_WANT_READ. */
|
||||||
|
inctx->block = APR_BLOCK_READ;
|
||||||
|
|
||||||
|
/* Handle custom errors. */
|
||||||
if (status != APR_SUCCESS) {
|
if (status != APR_SUCCESS) {
|
||||||
return ssl_io_filter_error(f, bb, status);
|
return ssl_io_filter_error(f, bb, status);
|
||||||
}
|
}
|
||||||
|
@@ -87,6 +87,29 @@ static apr_status_t upgrade_connection(request_rec *r)
|
|||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Perform a speculative (and non-blocking) read from the connection
|
||||||
|
* filters for the given request, to determine whether there is any
|
||||||
|
* pending data to read. Return non-zero if there is, else zero. */
|
||||||
|
static int has_buffered_data(request_rec *r)
|
||||||
|
{
|
||||||
|
apr_bucket_brigade *bb;
|
||||||
|
apr_off_t len;
|
||||||
|
apr_status_t rv;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
|
||||||
|
|
||||||
|
rv = ap_get_brigade(r->connection->input_filters, bb, AP_MODE_SPECULATIVE,
|
||||||
|
APR_NONBLOCK_READ, 1);
|
||||||
|
result = rv == APR_SUCCESS
|
||||||
|
&& apr_brigade_length(bb, 1, &len) == APR_SUCCESS
|
||||||
|
&& len > 0;
|
||||||
|
|
||||||
|
apr_brigade_destroy(bb);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Post Read Request Handler
|
* Post Read Request Handler
|
||||||
*/
|
*/
|
||||||
@@ -724,6 +747,23 @@ int ssl_hook_Access(request_rec *r)
|
|||||||
else {
|
else {
|
||||||
request_rec *id = r->main ? r->main : r;
|
request_rec *id = r->main ? r->main : r;
|
||||||
|
|
||||||
|
/* Additional mitigation for CVE-2009-3555: At this point,
|
||||||
|
* before renegotiating, an (entire) request has been read
|
||||||
|
* from the connection. An attacker may have sent further
|
||||||
|
* data to "prefix" any subsequent request by the victim's
|
||||||
|
* client after the renegotiation; this data may already
|
||||||
|
* have been read and buffered. Forcing a connection
|
||||||
|
* closure after the response ensures such data will be
|
||||||
|
* discarded. Legimately pipelined HTTP requests will be
|
||||||
|
* retried anyway with this approach. */
|
||||||
|
if (has_buffered_data(r)) {
|
||||||
|
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||||
|
"insecure SSL re-negotiation required, but "
|
||||||
|
"a pipelined request is present; keepalive "
|
||||||
|
"disabled");
|
||||||
|
r->connection->keepalive = AP_CONN_CLOSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* do a full renegotiation */
|
/* do a full renegotiation */
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
|
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
|
||||||
"Performing full renegotiation: "
|
"Performing full renegotiation: "
|
||||||
|
Reference in New Issue
Block a user