Skip to content

Commit 5d8a4eb

Browse files
committed
add support for respons headers and body processing
1 parent 995ea8e commit 5d8a4eb

File tree

6 files changed

+192
-34
lines changed

6 files changed

+192
-34
lines changed

dockerfiles/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ copy:
66
cp ../cmake-build-debug/libwafie.so /Users/dkartsev/.go/src/github.com/Dimss/wafie/cmd/modsecfilter
77
cp ../include/wafielib.h /Users/dkartsev/.go/src/github.com/Dimss/wafie/cmd/modsecfilter/include/wafie
88
build-modsec-runtime:
9+
podman build . -t modsec
910
podman manifest rm modsec-runtime --ignore
1011
podman build \
1112
--manifest modsec-runtime \

dockerfiles/empty-config/rules/REQUEST-800-CUSTOM-RULES.conf

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88

99
# SecRule REQUEST_URI "@rx .*" "id:1000008,phase:1,pass,log,msg:'DEBUG: The current REQUEST_URI is: %{REQUEST_URI}'"
1010

11-
SecAction \
12-
"id:1000003, \
13-
phase:1, \
14-
log, \
15-
deny, \
16-
status:401, \
17-
redirect:'add-header>FOO:BAR', \
18-
msg:'hello message'"
11+
SecRule REQUEST_METHOD "@streq POST" \
12+
"id:1000005,\
13+
phase:2,\
14+
pass,\
15+
nolog,\
16+
chain"
17+
SecRule REQUEST_URI "@streq /v2/g-recaptcha-response" \
18+
"t:none,\
19+
exec:/tmp/empty-config/rules/recaptchav2.lua"
1920

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function main()
2+
print("RUNNING RECAPTCHA v2 script")
3+
local token = m.getvar("ARGS_POST:g-recaptcha-response")
4+
print("token: " .. token)
5+
return nil
6+
end

include/wafielib.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,17 @@ typedef struct {
2323
char *uri;
2424
char *http_method;
2525
char *http_version;
26-
char *body;
26+
char *protocol;
27+
char *request_body;
28+
char *response_body;
2729
char *intervention_url;
28-
size_t headers_count;
30+
int response_code;
31+
size_t request_headers_count;
32+
size_t response_headers_count;
2933
int total_loaded_rules;
3034
uint32_t protection_id;
31-
WafieEvaluationRequestHeader *headers;
35+
WafieEvaluationRequestHeader *request_headers;
36+
WafieEvaluationRequestHeader *response_headers;
3237
Transaction *transaction;
3338
} WafieEvaluationRequest;
3439

@@ -44,4 +49,8 @@ int wafie_process_request_headers(WafieEvaluationRequest *request);
4449

4550
int wafie_process_request_body(WafieEvaluationRequest *request);
4651

52+
int wafie_process_response_headers(WafieEvaluationRequest *request);
53+
54+
int wafie_process_response_body(WafieEvaluationRequest *request);
55+
4756
#endif //WAFIELIB_LIBRARY_H

src/test.c

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,36 +67,60 @@ int main() {
6767
// cfg[1].config_path = "/config2";
6868

6969

70-
WafieEvaluationRequestHeader *headers1 = malloc(sizeof(WafieEvaluationRequestHeader) * 2);
70+
WafieEvaluationRequestHeader *headers1 = malloc(sizeof(WafieEvaluationRequestHeader) * 3);
7171
headers1[0].key = (const unsigned char *) "Host";
7272
headers1[0].value = (const unsigned char *) "example.com";
7373
headers1[1].key = (const unsigned char *) "User-Agent";
7474
headers1[1].value = (const unsigned char *) "KubeGuard/1.0";
75-
//
76-
//
75+
headers1[2].key = (const unsigned char *) "Content-Type";
76+
headers1[2].value = (const unsigned char *) "application/x-www-form-urlencoded";
77+
78+
WafieEvaluationRequestHeader *headers2 = malloc(sizeof(WafieEvaluationRequestHeader) * 3);
79+
headers2[0].key = (const unsigned char *) "Host";
80+
headers2[0].value = (const unsigned char *) "example.com";
81+
headers2[1].key = (const unsigned char *) "User-Agent";
82+
headers2[1].value = (const unsigned char *) "KubeGuard/1.0";
83+
headers2[2].key = (const unsigned char *) "Content-Type";
84+
headers2[2].value = (const unsigned char *) "application/x-www-form-urlencoded";
85+
// headers1[3].key = (const unsigned char *) "Content-Length";
86+
// headers1[3].value = (const unsigned char *) "7"; // strlen("foo=bar")
87+
7788
WafieEvaluationRequest request1 = {
7889
.client_ip = "192.168.127.1",
79-
.uri = "/wp-login.php",
80-
.http_method = "GET",
90+
.uri = "/v2/g-recaptcha-response",
91+
.http_method = "POST",
8192
.http_version = "1.1",
82-
.headers_count = 2,
83-
.headers = headers1,
84-
// .body = "",
93+
.request_headers_count = 3,
94+
.request_headers = headers1,
95+
.response_headers_count = 3,
96+
.response_headers = headers2,
97+
.response_code = 200,
98+
.protocol = "HTTP/1.1",
99+
// .body = "foo=bar",
85100
.protection_id = 1,
86101
};
102+
//
103+
//
87104

88105

89106
wafie_init();
90107
wafie_load_rule_sets(cfg, 1);
91108
wafie_init_transaction(&request1);
109+
//request
92110
wafie_process_request_headers(&request1);
93-
// wafie_process_request_body(&request1);
111+
request1.request_body = "foo=bar";
112+
wafie_process_request_body(&request1);
113+
// response
114+
wafie_process_response_headers(&request1);
115+
// request1.response_body = "{foo:bar}";
116+
wafie_process_response_body(&request1);
117+
//cleanup
94118
wafie_cleanup(&request1);
95119

96-
fprintf(stdout, "************** intervention url -> %s\n", request1.intervention_url);
97120

98121
free(headers1);
99122

123+
100124
char *audit_content = read_file("/tmp/modsec_audit.log");
101125
if (audit_content) {
102126
printf("Config loaded: %zu bytes\n", strlen(audit_content));

src/wafielib.c

Lines changed: 130 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ int wafie_process_intervention(WafieEvaluationRequest *request) {
202202
fprintf(stdout, "[libwafie.wafie_process_intervention.protection.id: %d] intervention triggered \n",
203203
request->protection_id);
204204
if (intervention.log != NULL) {
205-
fprintf(stdout, "%s\n", intervention.log);
205+
fprintf(stdout, "[intervention.log] %s\n", intervention.log);
206206
free(intervention.log);
207207
intervention.log = NULL;
208208
}
@@ -225,7 +225,7 @@ int wafie_process_intervention(WafieEvaluationRequest *request) {
225225
return 0;
226226
}
227227

228-
// process headers
228+
// process request headers
229229
int wafie_process_request_headers(WafieEvaluationRequest *request) {
230230
if (request->transaction == NULL) {
231231
fprintf(stdout, "[libwafie.wafie_process_request_headers.protection.id: %d] transaction is NULL, skipping \n",
@@ -261,12 +261,13 @@ int wafie_process_request_headers(WafieEvaluationRequest *request) {
261261
if (intervention_status != 0) {
262262
goto finish_processing;
263263
}
264-
for (size_t i = 0; i < request->headers_count; i++) {
265-
msc_add_request_header(request->transaction, request->headers[i].key, request->headers[i].value);
264+
for (size_t i = 0; i < request->request_headers_count; i++) {
265+
msc_add_request_header(request->transaction, request->request_headers[i].key,
266+
request->request_headers[i].value);
266267
fprintf(stdout, "[libwafie.wafie_process_request_headers.protection.id: %d] header -> %s: %s\n",
267268
request->protection_id,
268-
(const char *) request->headers[i].key,
269-
(const char *) request->headers[i].value);
269+
(const char *) request->request_headers[i].key,
270+
(const char *) request->request_headers[i].value);
270271
}
271272
fprintf(stdout, "[libwafie.wafie_process_request_headers.protection.id: %d] processing headers\n",
272273
request->protection_id);
@@ -294,7 +295,7 @@ int wafie_process_request_headers(WafieEvaluationRequest *request) {
294295
return intervention_status;
295296
}
296297

297-
// process body
298+
// process request body
298299
int wafie_process_request_body(WafieEvaluationRequest *request) {
299300
if (request->transaction == NULL) {
300301
fprintf(stdout, "[libwafie.wafie_process_request_body.protection.id: %d] transaction is NULL, skipping \n",
@@ -304,28 +305,144 @@ int wafie_process_request_body(WafieEvaluationRequest *request) {
304305
struct timespec start, end;
305306
int intervention_status = 0;
306307
// process request body
307-
if (request->body != NULL) {
308+
if (request->request_body != NULL) {
308309
fprintf(stdout, "[libwafie.wafie_process_request_body.protection.id: %d] processing request\n",
309310
request->protection_id);
310311
clock_gettime(CLOCK_MONOTONIC, &start);
311312
// append request body
312-
msc_append_request_body(request->transaction,
313-
(const unsigned char *) request->body,
314-
strlen(request->body));
313+
int const res = msc_append_request_body(request->transaction,
314+
(const unsigned char *) request->request_body,
315+
strlen(request->request_body));
316+
if (res == 0) {
317+
fprintf(
318+
stdout,
319+
"[libwafie.wafie_process_request_body.protection.id: %d] append request body failed return: %d\n",
320+
request->protection_id, res);
321+
}
315322
// process request body
316323
msc_process_request_body(request->transaction);
317324
// check for intervention
318325
intervention_status = wafie_process_intervention(request);
319326
clock_gettime(CLOCK_MONOTONIC, &end);
320327

321-
long long elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);
322-
double elapsed_ms = elapsed_ns / 1000000.0;
328+
long long const elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);
329+
double const elapsed_ms = elapsed_ns / 1000000.0;
323330
fprintf(stdout, "[libwafie.wafie_process_request_body.protection.id: %d] processing request took %.3f ms\n",
324331
request->protection_id, elapsed_ms);
325332

326333
if (intervention_status != 0) {
327334
return intervention_status;
328335
}
336+
} else {
337+
fprintf(stdout, "[libwafie.wafie_process_request_body.protection.id: %d] request body NULL, skipping \n",
338+
request->protection_id);
339+
}
340+
return intervention_status;
341+
}
342+
343+
// process response headers
344+
int wafie_process_response_headers(WafieEvaluationRequest *request) {
345+
if (request->transaction == NULL) {
346+
fprintf(stdout, "[libwafie.wafie_process_response_headers.protection.id: %d] transaction is NULL, skipping \n",
347+
request->protection_id);
348+
return 0;
349+
}
350+
if (request->response_headers_count == 0) {
351+
fprintf(stdout, "[libwafie.wafie_process_response_headers.protection.id: %d] no response headers, skipping \n",
352+
request->protection_id);
353+
return 0;
354+
}
355+
if (request->response_code == 0) {
356+
fprintf(stdout, "[libwafie.wafie_process_response_headers.protection.id: %d] no response code, skipping \n",
357+
request->protection_id);
358+
return 0;
359+
}
360+
if (request->protocol == NULL) {
361+
fprintf(stdout, "[libwafie.wafie_process_response_headers.protection.id: %d] no response protocol, skipping \n",
362+
request->protection_id);
363+
return 0;
364+
}
365+
struct timespec start, end;
366+
clock_gettime(CLOCK_MONOTONIC, &start);
367+
fprintf(stdout, "[libwafie.wafie_process_response_headers.protection.id: %d] processing request \n",
368+
request->protection_id);
369+
int intervention_status = 0;
370+
// add response headers to transaction
371+
for (size_t i = 0; i < request->response_headers_count; i++) {
372+
msc_add_response_header(request->transaction, request->response_headers[i].key,
373+
request->response_headers[i].value);
374+
fprintf(stdout, "[libwafie.wafie_process_response_headers.protection.id: %d] header -> %s: %s\n",
375+
request->protection_id,
376+
(const char *) request->response_headers[i].key,
377+
(const char *) request->response_headers[i].value);
378+
}
379+
fprintf(stdout, "[libwafie.wafie_process_response_headers.protection.id: %d] processing headers\n",
380+
request->protection_id);
381+
// process response headers phase
382+
msc_process_response_headers(request->transaction, request->response_code, request->protocol);
383+
intervention_status = wafie_process_intervention(request);
384+
if (intervention_status != 0) {
385+
goto finish_processing;
386+
}
387+
// process response body phase
388+
fprintf(stdout, "[libwafie.wafie_process_response_headers.protection.id: %d] processing body\n",
389+
request->protection_id);
390+
msc_process_response_body(request->transaction);
391+
intervention_status = wafie_process_intervention(request);
392+
// unconditionally finish processing once intervention detected
393+
finish_processing:
394+
clock_gettime(CLOCK_MONOTONIC, &end);
395+
long long elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);
396+
double elapsed_ms = elapsed_ns / 1000000.0;
397+
fprintf(
398+
stdout, "[libwafie.wafie_process_response_headers.protection.id: %d] processing request took %.3f ms\n",
399+
request->protection_id, elapsed_ms);
400+
fprintf(stdout, "[libwafie.wafie_process_response_headers.protection.id: %d] intervention status: %d\n",
401+
request->protection_id, intervention_status);
402+
return intervention_status;
403+
}
404+
405+
// process request body
406+
int wafie_process_response_body(WafieEvaluationRequest *request) {
407+
if (request->transaction == NULL) {
408+
fprintf(stdout, "[libwafie.wafie_process_response_body.protection.id: %d] transaction is NULL, skipping \n",
409+
request->protection_id);
410+
return 0;
411+
}
412+
struct timespec start, end;
413+
int intervention_status = 0;
414+
// process request body
415+
if (request->response_body != NULL) {
416+
fprintf(stdout, "[libwafie.wafie_process_response_body.protection.id: %d] processing request\n",
417+
request->protection_id);
418+
clock_gettime(CLOCK_MONOTONIC, &start);
419+
// append request body
420+
int const res = msc_append_response_body(request->transaction,
421+
(const unsigned char *) request->response_body,
422+
strlen(request->response_body));
423+
if (res == 0) {
424+
fprintf(
425+
stdout,
426+
"[libwafie.wafie_process_response_body.protection.id: %d] append response body failed return: %d\n",
427+
request->protection_id, res);
428+
}
429+
// process request body
430+
msc_process_response_body(request->transaction);
431+
// check for intervention
432+
intervention_status = wafie_process_intervention(request);
433+
clock_gettime(CLOCK_MONOTONIC, &end);
434+
435+
long long const elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);
436+
double const elapsed_ms = elapsed_ns / 1000000.0;
437+
fprintf(stdout, "[libwafie.wafie_process_response_body.protection.id: %d] processing request took %.3f ms\n",
438+
request->protection_id, elapsed_ms);
439+
440+
if (intervention_status != 0) {
441+
return intervention_status;
442+
}
443+
} else {
444+
fprintf(stdout, "[libwafie.wafie_process_response_body.protection.id: %d] response body NULL, skipping \n",
445+
request->protection_id);
329446
}
330447
return intervention_status;
331448
}

0 commit comments

Comments
 (0)