mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 13:56:01 +03:00
Nginx: Improved redirect action work for phases except log
This commit is contained in:
parent
e9af8a3ab1
commit
a951a83eec
@ -156,7 +156,8 @@ ngx_pstrdup0(ngx_pool_t *pool, ngx_str_t *src)
|
||||
}
|
||||
|
||||
|
||||
static inline int ngx_http_modsecurity_method_number(unsigned int nginx)
|
||||
static inline int
|
||||
ngx_http_modsecurity_method_number(unsigned int nginx)
|
||||
{
|
||||
/*
|
||||
* http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup
|
||||
@ -246,7 +247,7 @@ ngx_http_modsecurity_load_request(ngx_http_request_t *r)
|
||||
}
|
||||
#endif
|
||||
|
||||
req->parsed_uri.path = req->path_info;
|
||||
req->parsed_uri.path = (char *)ngx_pstrdup0(r->pool, &r->uri);
|
||||
req->parsed_uri.is_initialized = 1;
|
||||
|
||||
str.data = r->port_start;
|
||||
@ -254,7 +255,7 @@ ngx_http_modsecurity_load_request(ngx_http_request_t *r)
|
||||
req->parsed_uri.port = ngx_atoi(str.data, str.len);
|
||||
req->parsed_uri.port_str = (char *)ngx_pstrdup0(r->pool, &str);
|
||||
|
||||
req->parsed_uri.query = req->args;
|
||||
req->parsed_uri.query = r->args.len ? req->args : NULL;
|
||||
req->parsed_uri.dns_looked_up = 0;
|
||||
req->parsed_uri.dns_resolved = 0;
|
||||
|
||||
@ -786,6 +787,29 @@ ngx_http_modsecurity_save_headers_out_visitor(void *data, const char *key, const
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static ngx_inline ngx_int_t
|
||||
ngx_http_modsecurity_status(ngx_http_request_t *r, int status)
|
||||
{
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: status %d", status);
|
||||
|
||||
if (status == DECLINED || status == APR_SUCCESS) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
/* nginx known status */
|
||||
if ( (status >= 300 && status < 308) /* 3XX */
|
||||
|| (status >= 400 && status < 417) /* 4XX */
|
||||
|| (status >= 500 && status < 508) /* 5XX */
|
||||
|| (status == NGX_HTTP_CREATED || status == NGX_HTTP_NO_CONTENT) ) {
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* create loc conf struct */
|
||||
static void *
|
||||
ngx_http_modsecurity_create_loc_conf(ngx_conf_t *cf)
|
||||
@ -952,18 +976,18 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r)
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: handler");
|
||||
|
||||
/* create / retrive request ctx */
|
||||
if (r->internal) {
|
||||
/* we have already processed the request headers with previous loc conf */
|
||||
|
||||
/* TODO: do we need update ctx and process headers again? */
|
||||
ctx = ngx_http_get_module_pool_ctx(r, ngx_http_modsecurity);
|
||||
|
||||
if (ctx) {
|
||||
/* we have already processed the request headers */
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_modsecurity);
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: get internel request ctx failed");
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: request pool ctx empty");
|
||||
}
|
||||
|
||||
ctx = ngx_http_modsecurity_create_ctx(r);
|
||||
@ -978,23 +1002,24 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_http_modsecurity_load_request(r);
|
||||
|
||||
if (ngx_http_modsecurity_load_headers_in(r) != NGX_OK) {
|
||||
/* load request to request rec */
|
||||
if (ngx_http_modsecurity_load_request(r) != NGX_OK
|
||||
|| ngx_http_modsecurity_load_headers_in(r) != NGX_OK) {
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
/* processing request headers */
|
||||
rc = modsecProcessRequestHeaders(ctx->req);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestHeaders %d", rc);
|
||||
rc = ngx_http_modsecurity_status(r, modsecProcessRequestHeaders(ctx->req));
|
||||
|
||||
if (rc == DECLINED) {
|
||||
if (rc != NGX_DECLINED) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (modsecIsRequestBodyAccessEnabled(ctx->req)
|
||||
&& r->method == NGX_HTTP_POST) {
|
||||
if (r->method == NGX_HTTP_POST
|
||||
&& modsecIsRequestBodyAccessEnabled(ctx->req) ) {
|
||||
|
||||
/* Processing POST request body, should we process PUT? */
|
||||
/* read POST request body, should we process PUT? */
|
||||
rc = ngx_http_read_client_request_body(r, ngx_http_modsecurity_body_handler);
|
||||
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
|
||||
return rc;
|
||||
@ -1002,28 +1027,9 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r)
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
/* other method */
|
||||
rc = modsecProcessRequestBody(ctx->req);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestBody %d", rc);
|
||||
}
|
||||
|
||||
if (rc != DECLINED) {
|
||||
|
||||
/* Nginx and Apache share same response code */
|
||||
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK) {
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
*/
|
||||
|
||||
return NGX_DECLINED;
|
||||
return ngx_http_modsecurity_status(r, modsecProcessRequestBody(ctx->req));
|
||||
}
|
||||
|
||||
|
||||
@ -1038,19 +1044,12 @@ ngx_http_modsecurity_body_handler(ngx_http_request_t *r)
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
|
||||
|
||||
if (ngx_http_modsecurity_load_request_body(r) != NGX_OK) {
|
||||
|
||||
return ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
rc = modsecProcessRequestBody(ctx->req);
|
||||
rc = ngx_http_modsecurity_status(r, modsecProcessRequestBody(ctx->req));
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestBody %d", rc);
|
||||
|
||||
if (rc != DECLINED) {
|
||||
/* Nginx and Apache share same response code */
|
||||
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
|
||||
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
if (rc != NGX_DECLINED) {
|
||||
return ngx_http_finalize_request(r, rc);
|
||||
}
|
||||
|
||||
@ -1070,11 +1069,39 @@ static ngx_int_t
|
||||
ngx_http_modsecurity_header_filter(ngx_http_request_t *r) {
|
||||
ngx_http_modsecurity_loc_conf_t *cf;
|
||||
ngx_http_modsecurity_ctx_t *ctx;
|
||||
const char *location;
|
||||
ngx_table_elt_t *h;
|
||||
ngx_int_t rc;
|
||||
|
||||
|
||||
cf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity);
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
|
||||
|
||||
if (ctx && ctx->complete
|
||||
&& r->err_status >= NGX_HTTP_MOVED_PERMANENTLY
|
||||
&& r->err_status < 308) {
|
||||
|
||||
/* 3XX load redirect location header so that we can do redirec in phase 3,4 */
|
||||
location = apr_table_get(ctx->req->headers_out, "Location");
|
||||
|
||||
if (location == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
h = ngx_list_push(&r->headers_out.headers);
|
||||
if (h == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
h->hash = 1;
|
||||
h->key.data = (u_char *)"Location";
|
||||
h->key.len = ngx_strlen("Location");
|
||||
h->value.data = (u_char *)location;
|
||||
h->value.len = ngx_strlen(location);
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
if (r != r->main || !cf->enable || ctx->complete) {
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
@ -1091,10 +1118,11 @@ ngx_http_modsecurity_header_filter(ngx_http_request_t *r) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
rc = modsecProcessResponse(ctx->req);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessResponse %d", rc);
|
||||
rc = ngx_http_modsecurity_status(r, modsecProcessResponse(ctx->req));
|
||||
|
||||
if (rc == DECLINED || rc == APR_SUCCESS) {
|
||||
if (rc != NGX_DECLINED) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK
|
||||
|| ngx_http_modsecurity_save_headers_out(r) != NGX_OK) {
|
||||
@ -1104,13 +1132,6 @@ ngx_http_modsecurity_header_filter(ngx_http_request_t *r) {
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
|
||||
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -1142,24 +1163,20 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
}
|
||||
|
||||
/* last buf has been saved */
|
||||
|
||||
ctx->complete = 1;
|
||||
modsecSetResponseBrigade(ctx->req, ctx->brigade);
|
||||
|
||||
// TODO: do we need reload headers_in ?
|
||||
//
|
||||
if (ngx_http_modsecurity_load_headers_in(r) != NGX_OK
|
||||
|| ngx_http_modsecurity_load_headers_out(r) != NGX_OK) {
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
rc = modsecProcessResponse(ctx->req);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessResponse %d", rc);
|
||||
rc = ngx_http_modsecurity_status(r, modsecProcessResponse(ctx->req));
|
||||
|
||||
if (rc == DECLINED || rc == APR_SUCCESS) {
|
||||
|
||||
in = NULL;
|
||||
if (rc != NGX_DECLINED) {
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc);
|
||||
}
|
||||
|
||||
apr_brigade_length(ctx->brigade, 0, &content_length);
|
||||
|
||||
@ -1187,13 +1204,6 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
}
|
||||
|
||||
return ngx_http_next_body_filter(r, in);
|
||||
}
|
||||
|
||||
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
|
||||
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user