Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd93ce9c

Browse files
author
Felipe Zimmerle
committed
Adds REQUEST_FULL and REQUEST_FULL_LENGTH variables
This variable is a combination from REQUEST_LINE, REQUEST_HEADERS andREQUEST_BODY (if any). Expects for \n\n in between each of those values.
1 parent62f3d02 commitd93ce9c

File tree

7 files changed

+289
-2
lines changed

7 files changed

+289
-2
lines changed

‎apache2/mod_security2.c‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,8 @@ static modsec_rec *create_tx_context(request_rec *r) {
519519
msr->request_headers=apr_table_copy(msr->mp,r->headers_in);
520520
msr->hostname=ap_get_server_name(r);
521521

522+
msr->msc_full_request_buffer=NULL;
523+
msr->msc_full_request_length=0;
522524
msr->msc_rule_mptmp=NULL;
523525

524526
/* Invoke the engine to continue with initialisation */

‎apache2/modsecurity.c‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,12 @@ static apr_status_t modsecurity_tx_cleanup(void *data) {
261261
msr_log(msr,1,"%s",my_error_msg);
262262
}
263263

264+
if (msr->msc_full_request_length>0&&
265+
msr->msc_full_request_buffer!=NULL) {
266+
msr->msc_full_request_length=0;
267+
free(msr->msc_full_request_buffer);
268+
}
269+
264270
#if defined(WITH_LUA)
265271
#ifdefCACHE_LUA
266272
if(msr->L!=NULL)lua_close(msr->L);

‎apache2/modsecurity.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,9 @@ struct modsec_rec {
355355

356356
apr_size_tmsc_reqbody_no_files_length;
357357

358+
char*msc_full_request_buffer;
359+
intmsc_full_request_length;
360+
358361
char*multipart_filename;
359362
char*multipart_name;
360363
multipart_data*mpd;/* MULTIPART processor data structure */

‎apache2/msc_util.c‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2386,3 +2386,69 @@ char *construct_single_var(modsec_rec *msr, char *name) {
23862386

23872387
return (char*)vx->value;
23882388
}
2389+
2390+
2391+
/**
2392+
* @brief Transforms an apr_array_header_t to a text buffer
2393+
*
2394+
* Converts an apr_array_header_t into a plain/text buffer in a Key: Pair
2395+
* format. The generated buffer is not null terminated.
2396+
*
2397+
* If called with `buffer_length` set to 0 or with `buffer` set to NULL,
2398+
* it will _not_ fill any buffer, instead, it will return the length, that
2399+
* will be needed to save the entire content of `arr` into a buffer.
2400+
*
2401+
* @warning return is not NULL-terminated.
2402+
* @note memory management is in the responsibility of the caller.
2403+
*
2404+
* @param arr apr_array_header_t to be iterated.
2405+
* @param buffer pointer to the destination buffer.
2406+
* @param buffer_length length that will fully fill the buffer.
2407+
* @retval -1 Something went wrong in the process. Do not trust in
2408+
* buffer content.
2409+
* @retval n>0 size of the [needed|] buffer.
2410+
*
2411+
*/
2412+
intmsc_headers_to_buffer(constapr_array_header_t*arr,char*buffer,
2413+
intbuffer_length)
2414+
{
2415+
intheaders_length=0;
2416+
intwrite_to_buffer=0;
2417+
inti=0;
2418+
constapr_table_entry_t*te=NULL;
2419+
2420+
if (buffer!=NULL&&buffer_length>0) {
2421+
write_to_buffer=1;
2422+
}
2423+
2424+
te= (apr_table_entry_t*)arr->elts;
2425+
for (i=0;i<arr->nelts;i++) {
2426+
char*value=te[i].val;
2427+
char*key=te[i].key;
2428+
headers_length=headers_length+strlen(value)+strlen(key)+/* \n: */1+
2429+
/* colum */1+/* space: */1 ;
2430+
2431+
if (write_to_buffer==1) {
2432+
if (buffer_length<headers_length) {
2433+
headers_length=-1;
2434+
gotonot_enough_memory;
2435+
}
2436+
2437+
sprintf(buffer,"%s%s: %s\n",buffer,key,value);
2438+
}
2439+
}
2440+
2441+
headers_length++;/* Save space for an extra '\n' between the hedaers and the request body */
2442+
if (write_to_buffer) {
2443+
if (buffer_length<headers_length) {
2444+
headers_length=-1;
2445+
gotonot_enough_memory;
2446+
}
2447+
2448+
buffer[headers_length-1]='\n';
2449+
}
2450+
2451+
not_enough_memory:
2452+
returnheaders_length;
2453+
}
2454+

‎apache2/msc_util.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,6 @@ char DSOLOCAL *format_all_performance_variables(modsec_rec *msr, apr_pool_t *mp)
149149
unsignedcharDSOLOCALis_netmask_v4(char*ip_strv4);
150150

151151
unsignedcharDSOLOCALis_netmask_v6(char*ip_strv6);
152+
153+
intDSOLOCALmsc_headers_to_buffer(constapr_array_header_t*arr,char*buffer,intmax_length);
152154
#endif

‎apache2/re_variables.c‎

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1934,6 +1934,87 @@ static int var_request_basename_generate(modsec_rec *msr, msre_var *var, msre_ru
19341934
returnvar_simple_generate(var,vartab,mptmp,value);
19351935
}
19361936

1937+
/* FULL_REQUEST */
1938+
1939+
staticintvar_full_request_generate(modsec_rec*msr,msre_var*var,
1940+
msre_rule*rule,apr_table_t*vartab,apr_pool_t*mptmp)
1941+
{
1942+
constapr_array_header_t*arr=NULL;
1943+
char*full_request=NULL;
1944+
intfull_request_length=0;
1945+
intheaders_length=0;
1946+
intrequest_line_length=0;
1947+
1948+
arr=apr_table_elts(msr->request_headers);
1949+
headers_length=msc_headers_to_buffer(arr,NULL,0);
1950+
if (headers_length<0) {
1951+
msr_log(msr,9,"Variable FULL_REQUEST failed. Problems to measure " \
1952+
"headers length.");
1953+
gotofailed_measure_buffer;
1954+
}
1955+
1956+
request_line_length=strlen(msr->request_line)+/* \n\n: */2;
1957+
full_request_length=request_line_length+headers_length+
1958+
msr->msc_reqbody_length+/* \0: */1;
1959+
1960+
full_request=malloc(sizeof(char)*full_request_length);
1961+
if (full_request==NULL) {
1962+
if (msr->txcfg->debuglog_level >=9) {
1963+
msr_log(msr,8,"Variable FULL_REQUEST will not be created, not " \
1964+
"enough memory available.");
1965+
}
1966+
gotofailed_not_enough_mem;
1967+
}
1968+
memset(full_request,'\0',sizeof(char)*msr->msc_full_request_length);
1969+
msr->msc_full_request_buffer=full_request;
1970+
msr->msc_full_request_length=full_request_length;
1971+
1972+
apr_snprintf(full_request,request_line_length+1,
1973+
/* +1 here because sprintf will place \0 in the end of the string.*/
1974+
"%s\n\n",msr->request_line);
1975+
1976+
headers_length=msc_headers_to_buffer(arr,full_request+
1977+
request_line_length,headers_length);
1978+
if (headers_length<0) {
1979+
msr_log(msr,9,"Variable FULL_REQUEST will not be created, failed " \
1980+
"to fill headers buffer.");
1981+
gotofailed_fill_buffer;
1982+
}
1983+
1984+
if (msr->msc_reqbody_length>0&&msr->msc_reqbody_buffer!=NULL) {
1985+
memcpy(full_request+ (headers_length+request_line_length),
1986+
msr->msc_reqbody_buffer,msr->msc_reqbody_length);
1987+
}
1988+
full_request[msr->msc_full_request_length-1]='\0';
1989+
1990+
returnvar_simple_generate_ex(var,vartab,mptmp,full_request,
1991+
msr->msc_full_request_length);
1992+
1993+
failed_fill_buffer:
1994+
failed_not_enough_mem:
1995+
failed_measure_buffer:
1996+
no_buffer:
1997+
return0;
1998+
}
1999+
2000+
/* FULL_REQUEST_LENGTH */
2001+
2002+
staticintvar_full_request_length_generate(modsec_rec*msr,msre_var*var,msre_rule*rule,
2003+
apr_table_t*vartab,apr_pool_t*mptmp)
2004+
{
2005+
constapr_array_header_t*arr=NULL;
2006+
char*value=NULL;
2007+
intheaders_length=0;
2008+
2009+
arr=apr_table_elts(msr->request_headers);
2010+
headers_length=msc_headers_to_buffer(arr,NULL,0);
2011+
msr->msc_full_request_length=headers_length+msr->msc_reqbody_length+/* \0: */1;
2012+
2013+
value=apr_psprintf(mptmp,"%d",msr->msc_full_request_length);
2014+
returnvar_simple_generate(var,vartab,mptmp,value);
2015+
}
2016+
2017+
19372018
/* REQUEST_BODY */
19382019

19392020
staticintvar_request_body_generate(modsec_rec*msr,msre_var*var,msre_rule*rule,
@@ -3204,12 +3285,35 @@ void msre_engine_register_default_variables(msre_engine *engine) {
32043285
PHASE_REQUEST_HEADERS
32053286
);
32063287

3207-
/*REQUEST_BODY */
3288+
/*FULL_REQUEST */
32083289
msre_engine_variable_register(engine,
3209-
"REQUEST_BODY",
3290+
"FULL_REQUEST",
32103291
VAR_SIMPLE,
32113292
0,0,
32123293
NULL,
3294+
var_full_request_generate,
3295+
VAR_CACHE,
3296+
PHASE_REQUEST_BODY
3297+
);
3298+
3299+
/* FULL_REQUEST_LENGTH */
3300+
msre_engine_variable_register(engine,
3301+
"FULL_REQUEST_LENGTH",
3302+
VAR_SIMPLE,
3303+
0,0,
3304+
NULL,
3305+
var_full_request_length_generate,
3306+
VAR_CACHE,
3307+
PHASE_REQUEST_BODY
3308+
);
3309+
3310+
3311+
/* REQUEST_BODY */
3312+
msre_engine_variable_register(engine,
3313+
"REQUEST_BODY",
3314+
VAR_LIST,
3315+
0,1,
3316+
var_generic_list_validate,
32133317
var_request_body_generate,
32143318
VAR_CACHE,
32153319
PHASE_REQUEST_BODY

‎tests/regression/target/00-targets.t‎

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,110 @@
373373
"arg1=val1&arg2=val2",
374374
),
375375
},
376+
# FULL_REQUEST
377+
{
378+
type=>"target",
379+
comment=>"FULL_REQUEST (get)",
380+
conf=> qq(
381+
SecRuleEngine On
382+
SecRequestBodyAccess On
383+
SecResponseBodyAccess On
384+
SecDebugLog$ENV{DEBUG_LOG}
385+
SecDebugLogLevel9
386+
SecRule FULL_REQUEST"arg1""phase:4,log,pass,id:500211"
387+
SecRule FULL_REQUEST"arg2""phase:4,log,pass,id:500212"
388+
),
389+
match_log=> {
390+
error=> [ qr/Patternmatch"arg1" at FULL_REQUEST.*Patternmatch"arg2" at FULL_REQUEST/s,1 ],
391+
debug=> [ qr/against FULL_REQUEST.*Targetvalue:"GET \/test.txt\?arg1=val1\&arg2=val2 HTTP\/1.1\\n\\nTE: deflate,gzip;q=0.3\\nConnection: TE, close\\nHost: localhost:8088\\nUser-Agent: ModSecurity Regression Tests\/1.2.3\\n\\n\\x00"/s,1],
392+
},
393+
match_response=> {
394+
status=> qr/^200$/,
395+
},
396+
request=>new HTTP::Request(
397+
GET=>"http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
398+
),
399+
},
400+
{
401+
type=>"target",
402+
comment=>"FULL_REQUEST (post)",
403+
conf=> qq(
404+
SecRuleEngine On
405+
SecRequestBodyAccess On
406+
SecResponseBodyAccess On
407+
SecDebugLog$ENV{DEBUG_LOG}
408+
SecDebugLogLevel9
409+
SecRule FULL_REQUEST"arg1""phase:4,log,pass,id:500213"
410+
SecRule FULL_REQUEST"arg2""phase:4,log,pass,id:500214"
411+
),
412+
match_log=> {
413+
error=> [ qr/Patternmatch"arg1" at FULL_REQUEST.*Patternmatch"arg2" at FULL_REQUEST/s,1 ],
414+
debug=> [ qr/against FULL_REQUEST.*Targetvalue:"POST \/test.txt HTTP\/1.1\\n\\nTE: deflate,gzip;q=0.3\\nConnection: TE, close\\nHost: localhost:8088\\nUser-Agent: ModSecurity Regression Tests\/1.2.3\\nContent-Type: application\/x-www-form-urlencoded\\nContent-Length: 19\\n\\narg1=val1&arg2=val2\\x00"/s,1 ],
415+
},
416+
match_response=> {
417+
status=> qr/^200$/,
418+
},
419+
request=>new HTTP::Request(
420+
POST=>"http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
421+
[
422+
"Content-Type"=>"application/x-www-form-urlencoded",
423+
],
424+
"arg1=val1&arg2=val2",
425+
),
426+
},
427+
# FULL_REQUEST_LENGTH
428+
{
429+
type=>"target",
430+
comment=>"FULL_REQUEST_LENGTH (get)",
431+
conf=> qq(
432+
SecRuleEngine On
433+
SecRequestBodyAccess On
434+
SecResponseBodyAccess On
435+
SecDebugLog$ENV{DEBUG_LOG}
436+
SecDebugLogLevel9
437+
SecRule FULL_REQUEST_LENGTH"\@eq 1""phase:4,log,pass,id:500211"
438+
SecRule FULL_REQUEST_LENGTH"\@eq 115""phase:4,log,pass,id:500212"
439+
),
440+
match_log=> {
441+
error=> [ qr/Operator EQ matched115 at FULL_REQUEST_LENGTH./s,1 ],
442+
debug=> [ qr/against FULL_REQUEST_LENGTH.*Targetvalue:"115"/s,1 ],
443+
},
444+
match_response=> {
445+
status=> qr/^200$/,
446+
},
447+
request=>new HTTP::Request(
448+
GET=>"http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
449+
),
450+
},
451+
{
452+
type=>"target",
453+
comment=>"FULL_REQUEST_LENGTH (post)",
454+
conf=> qq(
455+
SecRuleEngine On
456+
SecRequestBodyAccess On
457+
SecResponseBodyAccess On
458+
SecDebugLog$ENV{DEBUG_LOG}
459+
SecDebugLogLevel9
460+
SecRule FULL_REQUEST_LENGTH"\@eq 1""phase:4,log,pass,id:500213"
461+
SecRule FULL_REQUEST_LENGTH"\@eq 201""phase:4,log,pass,id:500214"
462+
),
463+
match_log=> {
464+
error=> [ qr/Operator EQ matched201 at FULL_REQUEST_LENGTH./s,1 ],
465+
debug=> [ qr/against FULL_REQUEST_LENGTH.*Targetvalue:"201"/s,1 ],
466+
},
467+
match_response=> {
468+
status=> qr/^200$/,
469+
},
470+
request=>new HTTP::Request(
471+
POST=>"http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
472+
[
473+
"Content-Type"=>"application/x-www-form-urlencoded",
474+
],
475+
"arg1=val1&arg2=val2",
476+
),
477+
},
478+
479+
376480

377481
# AUTH_TYPE
378482
#{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp