1
0
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:
Nick Kew
2017-04-21 08:44:06 +00:00
parent b517584604
commit 38e269322b
7 changed files with 60 additions and 1 deletions

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 &&

View File

@@ -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;

View File

@@ -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_;