mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
Introduce request taint-checking concept.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1792169 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,6 +1,9 @@
|
|||||||
-*- coding: utf-8 -*-
|
-*- coding: utf-8 -*-
|
||||||
Changes with Apache 2.5.0
|
Changes with Apache 2.5.0
|
||||||
|
|
||||||
|
*) Introduce request taint checking framework to prevent privilege
|
||||||
|
hijacking through .htaccess. [Nick Kew]
|
||||||
|
|
||||||
*) mod_proxy_wstunnel: Add "upgrade" parameter to allow upgrade to other
|
*) mod_proxy_wstunnel: Add "upgrade" parameter to allow upgrade to other
|
||||||
protocols. [Jean-Frederic Clere]
|
protocols. [Jean-Frederic Clere]
|
||||||
|
|
||||||
|
@@ -551,6 +551,7 @@
|
|||||||
* Added ap_scan_vchar_obstext()
|
* Added ap_scan_vchar_obstext()
|
||||||
* 20161018.2 (2.5.0-dev) add ap_set_conn_count()
|
* 20161018.2 (2.5.0-dev) add ap_set_conn_count()
|
||||||
* 20161018.3 (2.5.0-dev) add ap_exists_directive()
|
* 20161018.3 (2.5.0-dev) add ap_exists_directive()
|
||||||
|
* 20161018.4 (2.5.0-dev) Add taint to request_rec and ap_request_tainted()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
|
#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
|
||||||
@@ -558,7 +559,7 @@
|
|||||||
#ifndef MODULE_MAGIC_NUMBER_MAJOR
|
#ifndef MODULE_MAGIC_NUMBER_MAJOR
|
||||||
#define MODULE_MAGIC_NUMBER_MAJOR 20161018
|
#define MODULE_MAGIC_NUMBER_MAJOR 20161018
|
||||||
#endif
|
#endif
|
||||||
#define MODULE_MAGIC_NUMBER_MINOR 3 /* 0...n */
|
#define MODULE_MAGIC_NUMBER_MINOR 4 /* 0...n */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
|
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
|
||||||
|
@@ -1074,6 +1074,11 @@ struct request_rec {
|
|||||||
* TODO: 2 bit signed bitfield when this structure is compacted
|
* TODO: 2 bit signed bitfield when this structure is compacted
|
||||||
*/
|
*/
|
||||||
int double_reverse;
|
int double_reverse;
|
||||||
|
/** Mark the request as potentially tainted. This might become a
|
||||||
|
* bitfield if we identify different taints to be flagged.
|
||||||
|
* Always use ap_request_tainted() to check taint.
|
||||||
|
*/
|
||||||
|
int taint;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2153,6 +2158,17 @@ AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
|
|||||||
*/
|
*/
|
||||||
AP_DECLARE(int) ap_request_has_body(request_rec *r);
|
AP_DECLARE(int) ap_request_has_body(request_rec *r);
|
||||||
|
|
||||||
|
/** Request taint flags. Only .htaccess defined. */
|
||||||
|
#define AP_TAINT_HTACCESS 0x1
|
||||||
|
/**
|
||||||
|
* Check whether a request is tainted by potentially-untrusted sources.
|
||||||
|
*
|
||||||
|
* @param r the request
|
||||||
|
* @param flags Taint flags to check
|
||||||
|
* @return truth value
|
||||||
|
*/
|
||||||
|
AP_DECLARE(int) ap_request_tainted(request_rec *r, int flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleanup a string (mainly to be filesystem safe)
|
* Cleanup a string (mainly to be filesystem safe)
|
||||||
* We only allow '_' and alphanumeric chars. Non-printable
|
* We only allow '_' and alphanumeric chars. Non-printable
|
||||||
|
@@ -213,6 +213,13 @@ static int status_handler(request_rec *r)
|
|||||||
return DECLINED;
|
return DECLINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A request that has passed through .htaccess has no business
|
||||||
|
* landing up here.
|
||||||
|
*/
|
||||||
|
if (ap_request_tainted(r, AP_TAINT_HTACCESS)) {
|
||||||
|
return DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TIMES
|
#ifdef HAVE_TIMES
|
||||||
times_per_thread = getpid() != child_pid;
|
times_per_thread = getpid() != child_pid;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -932,6 +932,14 @@ static int proxy_fixup(request_rec *r)
|
|||||||
if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0)
|
if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0)
|
||||||
return DECLINED;
|
return DECLINED;
|
||||||
|
|
||||||
|
/* A request that has passed through .htaccess has no business
|
||||||
|
* serving contents from so far outside its directory.
|
||||||
|
* Since we're going to decline it, don't waste time here.
|
||||||
|
*/
|
||||||
|
if (ap_request_tainted(r, AP_TAINT_HTACCESS)) {
|
||||||
|
return DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX: Shouldn't we try this before we run the proxy_walk? */
|
/* XXX: Shouldn't we try this before we run the proxy_walk? */
|
||||||
url = &r->filename[6];
|
url = &r->filename[6];
|
||||||
|
|
||||||
@@ -1025,6 +1033,13 @@ static int proxy_handler(request_rec *r)
|
|||||||
return DECLINED;
|
return DECLINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A request that has passed through .htaccess has no business
|
||||||
|
* serving contents from so far outside its directory.
|
||||||
|
*/
|
||||||
|
if (ap_request_tainted(r, AP_TAINT_HTACCESS)) {
|
||||||
|
return DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
if (!r->proxyreq) {
|
if (!r->proxyreq) {
|
||||||
/* We may have forced the proxy handler via config or .htaccess */
|
/* We may have forced the proxy handler via config or .htaccess */
|
||||||
if (r->handler &&
|
if (r->handler &&
|
||||||
|
@@ -2196,6 +2196,8 @@ AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result,
|
|||||||
const char *errmsg;
|
const char *errmsg;
|
||||||
ap_directive_t *temptree = NULL;
|
ap_directive_t *temptree = NULL;
|
||||||
|
|
||||||
|
/* Mark the request as tainted by .htaccess */
|
||||||
|
r->taint |= AP_TAINT_HTACCESS;
|
||||||
dc = ap_create_per_dir_config(r->pool);
|
dc = ap_create_per_dir_config(r->pool);
|
||||||
|
|
||||||
parms.config_file = f;
|
parms.config_file = f;
|
||||||
|
@@ -2580,6 +2580,21 @@ AP_DECLARE(int) ap_request_has_body(request_rec *r)
|
|||||||
return has_body;
|
return has_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a request is tainted by exposure to something
|
||||||
|
* potentially untrusted.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
AP_DECLARE(int) ap_request_tainted(request_rec *r, int flags)
|
||||||
|
{
|
||||||
|
/** Potential future: a hook or callback here could serve modules
|
||||||
|
* like mod_security and ironbee with more complex needs.
|
||||||
|
*/
|
||||||
|
return r && ((r->taint&flags)
|
||||||
|
|| ap_request_tainted(r->main, flags)
|
||||||
|
|| ap_request_tainted(r->prev, flags));
|
||||||
|
}
|
||||||
|
|
||||||
AP_DECLARE_NONSTD(apr_status_t) ap_pool_cleanup_set_null(void *data_)
|
AP_DECLARE_NONSTD(apr_status_t) ap_pool_cleanup_set_null(void *data_)
|
||||||
{
|
{
|
||||||
void **ptr = (void **)data_;
|
void **ptr = (void **)data_;
|
||||||
|
Reference in New Issue
Block a user