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 -*-
|
||||
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
|
||||
protocols. [Jean-Frederic Clere]
|
||||
|
||||
|
@@ -551,6 +551,7 @@
|
||||
* Added ap_scan_vchar_obstext()
|
||||
* 20161018.2 (2.5.0-dev) add ap_set_conn_count()
|
||||
* 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" */
|
||||
@@ -558,7 +559,7 @@
|
||||
#ifndef MODULE_MAGIC_NUMBER_MAJOR
|
||||
#define MODULE_MAGIC_NUMBER_MAJOR 20161018
|
||||
#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
|
||||
|
@@ -1074,6 +1074,11 @@ struct request_rec {
|
||||
* TODO: 2 bit signed bitfield when this structure is compacted
|
||||
*/
|
||||
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);
|
||||
|
||||
/** 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)
|
||||
* We only allow '_' and alphanumeric chars. Non-printable
|
||||
|
@@ -213,6 +213,13 @@ static int status_handler(request_rec *r)
|
||||
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
|
||||
times_per_thread = getpid() != child_pid;
|
||||
#endif
|
||||
|
@@ -932,6 +932,14 @@ static int proxy_fixup(request_rec *r)
|
||||
if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0)
|
||||
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? */
|
||||
url = &r->filename[6];
|
||||
|
||||
@@ -1025,6 +1033,13 @@ static int proxy_handler(request_rec *r)
|
||||
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) {
|
||||
/* We may have forced the proxy handler via config or .htaccess */
|
||||
if (r->handler &&
|
||||
|
@@ -2196,6 +2196,8 @@ AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result,
|
||||
const char *errmsg;
|
||||
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);
|
||||
|
||||
parms.config_file = f;
|
||||
|
@@ -2580,6 +2580,21 @@ AP_DECLARE(int) ap_request_has_body(request_rec *r)
|
||||
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_)
|
||||
{
|
||||
void **ptr = (void **)data_;
|
||||
|
Reference in New Issue
Block a user