912
** check variable + name against a set of rules, checking against 'custom' location rules too.
914
** check variable + name against a set of rules, checking against 'custom' location rules too.
914
916
#define basestr_ruleset_debug
917
ngx_http_basestr_ruleset_n(ngx_pool_t *pool,
921
ngx_http_request_t *req,
922
ngx_http_request_ctx_t *ctx,
923
enum DUMMY_MATCH_ZONE zone)
926
unsigned int i, ret, z;
928
ngx_http_custom_rule_location_t *location;
929
ngx_http_dummy_loc_conf_t *cf;
919
ngx_http_basestr_ruleset_n(ngx_pool_t *pool,
923
ngx_http_request_t *req,
924
ngx_http_request_ctx_t *ctx,
925
enum DUMMY_MATCH_ZONE zone)
928
unsigned int i, ret, z;
930
ngx_http_custom_rule_location_t *location;
931
ngx_http_dummy_loc_conf_t *cf;
931
933
#ifdef basestr_ruleset_debug
932
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
933
"XX-check check [%V]=[%V] in zone %s", name, value,
934
zone == BODY ? "BODY" : zone == HEADERS ? "HEADERS" : zone == URL ? "URL" :
935
zone == ARGS ? "ARGS" : "UNKNOWN");
939
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
940
"XX-no rules, wtf ?!");
944
cf = ngx_http_get_module_loc_conf(req, ngx_http_naxsi_module);
945
#ifdef basestr_ruleset_debug
946
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
947
"XX-checking rules ...");
950
for (i = 0; i < rules->nelts && (!ctx->block || cf->learning) ; i++) {
951
#ifdef basestr_ruleset_debug
952
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
953
"XX-rule %d (%V=%V)", r[i].rule_id, name, value);
934
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
935
"XX-check check [%V]=[%V] in zone %s", name, value,
936
zone == BODY ? "BODY" : zone == HEADERS ? "HEADERS" : zone == URL ? "URL" :
937
zone == ARGS ? "ARGS" : "UNKNOWN");
941
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
942
"XX-no rules, wtf ?!");
946
cf = ngx_http_get_module_loc_conf(req, ngx_http_naxsi_module);
947
#ifdef basestr_ruleset_debug
948
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
949
"XX-checking rules ...");
952
for (i = 0; i < rules->nelts && (!ctx->block || cf->learning) ; i++) {
953
#ifdef basestr_ruleset_debug
954
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
955
"XX-rule %d (%V=%V)", r[i].rule_id, name, value);
956
/* does the rule have a custom location ? custom location means checking only on a specific argument */
957
if (name && name->len > 0 && r[i].br->custom_location) {
958
location = r[i].br->custom_locations->elts;
959
/* for each custom location */
960
for (z = 0; z < r[i].br->custom_locations->nelts; z++) {
961
/* if the name are the same, check */
962
if (name->len == location[z].target.len &&
963
!strncasecmp((const char *)name->data,
964
(const char *) location[z].target.data,
965
location[z].target.len)) {
958
/* does the rule have a custom location ? custom location means checking only on a specific argument */
959
if (name && name->len > 0 && r[i].br->custom_location) {
960
location = r[i].br->custom_locations->elts;
961
/* for each custom location */
962
for (z = 0; z < r[i].br->custom_locations->nelts; z++) {
963
/* if the name are the same, check */
964
if (name->len == location[z].target.len &&
965
!strncasecmp((const char *)name->data,
966
(const char *) location[z].target.data,
967
location[z].target.len)) {
967
969
#ifdef basestr_ruleset_debug
968
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
969
"XX-[SPECIFIC] check one rule [%d] iteration %d * %d", r[i].rule_id, i, z);
971
/* match rule against var content, */
970
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
971
"XX-[SPECIFIC] check one rule [%d] iteration %d * %d", r[i].rule_id, i, z);
973
/* match rule against var content, */
974
ret = ngx_http_process_basic_rule_buffer(value, &(r[i]), &nb_match);
975
//if our rule matched, apply effects (score etc.)
977
#ifdef basestr_ruleset_debug
978
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
979
"XX-apply rulematch!! [%V]=[%V] [rule=%d] (match %d times)", name, value, r[i].rule_id, nb_match);
981
ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 0);
984
if (!r[i].br->negative) {
985
/* match rule against var name, */
986
ret = ngx_http_process_basic_rule_buffer(name, &(r[i]), &nb_match);
987
//if our rule matched, apply effects (score etc.)
989
#ifdef basestr_ruleset_debug
990
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
991
"XX-apply rulematch[in name] [%V]=[%V] [rule=%d] (match %d times)", name, value, r[i].rule_id, nb_match);
993
ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, name, zone, nb_match, 1);
1005
** check against the rule if the current zone is matching
1006
** the zone the rule is meant to be check against
1008
if ( (zone == HEADERS && r[i].br->headers) ||
1009
(zone == URL && r[i].br->url) ||
1010
(zone == ARGS && r[i].br->args) ||
1011
(zone == BODY && r[i].br->body && !r[i].br->file_ext) ||
1012
(zone == FILE_EXT && r[i].br->file_ext) ) {
1014
/* #ifdef basestr_ruleset_debug */
1015
/* ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, */
1016
/* "XX-check [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match); */
1019
#ifdef basestr_ruleset_debug
1020
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
1021
"XX-test rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match);
1024
/* check the rule against the value*/
972
1025
ret = ngx_http_process_basic_rule_buffer(value, &(r[i]), &nb_match);
973
//if our rule matched, apply effects (score etc.)
1026
/*if our rule matched, apply effects (score etc.)*/
975
1028
#ifdef basestr_ruleset_debug
976
1029
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
977
"XX-apply rulematch!! [%V]=[%V] [rule=%d] (match %d times)", name, value, r[i].rule_id, nb_match);
1030
"XX-apply rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match);
979
ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 0);
1032
ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 0);
982
if (!r[i].br->negative) {
983
/* match rule against var name, */
1035
if (!r[i].br->negative) {
1036
#ifdef basestr_ruleset_debug
1037
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
1038
"XX-test rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match);
1040
/* check the rule against the name*/
984
1041
ret = ngx_http_process_basic_rule_buffer(name, &(r[i]), &nb_match);
985
//if our rule matched, apply effects (score etc.)
1042
/*if our rule matched, apply effects (score etc.)*/
987
1044
#ifdef basestr_ruleset_debug
988
1045
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
989
"XX-apply rulematch[in name] [%V]=[%V] [rule=%d] (match %d times)", name, value, r[i].rule_id, nb_match);
1046
"XX-apply rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match);
991
ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, name, zone, nb_match, 1);
1048
ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 1);
1003
** check against the rule if the current zone is matching
1004
** the zone the rule is meant to be check against
1060
** does : parse body data, a.k.a POST/PUT datas. identifies content-type,
1061
** and, if appropriate, boundary. then parse the stuff if multipart/for..
1062
** or rely on spliturl if application/x-w..
1063
** [XXX] : this function sucks ! I don't parse bigger-than-body-size posts that
1064
** are partially stored in files, TODO ;)
1006
if ( (zone == HEADERS && r[i].br->headers) ||
1007
(zone == URL && r[i].br->url) ||
1008
(zone == ARGS && r[i].br->args) ||
1009
(zone == BODY && r[i].br->body && !r[i].br->file_ext) ||
1010
(zone == FILE_EXT && r[i].br->file_ext) ) {
1012
/* #ifdef basestr_ruleset_debug */
1013
/* ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0, */
1014
/* "XX-check [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match); */
1017
#ifdef basestr_ruleset_debug
1018
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
1019
"XX-test rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match);
1022
/* check the rule against the value*/
1023
ret = ngx_http_process_basic_rule_buffer(value, &(r[i]), &nb_match);
1024
/*if our rule matched, apply effects (score etc.)*/
1026
#ifdef basestr_ruleset_debug
1027
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
1028
"XX-apply rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match);
1030
ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 0);
1033
if (!r[i].br->negative) {
1034
#ifdef basestr_ruleset_debug
1035
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
1036
"XX-test rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match);
1038
/* check the rule against the name*/
1039
ret = ngx_http_process_basic_rule_buffer(name, &(r[i]), &nb_match);
1040
/*if our rule matched, apply effects (score etc.)*/
1042
#ifdef basestr_ruleset_debug
1043
ngx_log_debug(NGX_LOG_DEBUG_HTTP, req->connection->log, 0,
1044
"XX-apply rulematch!1 [%V]=[%V] [rule=%d] (%d times)", name, value, r[i].rule_id, nb_match);
1046
ngx_http_apply_rulematch_v_n(&(r[i]), ctx, req, name, value, zone, nb_match, 1);
1058
** does : parse body data, a.k.a POST/PUT datas. identifies content-type,
1059
** and, if appropriate, boundary. then parse the stuff if multipart/for..
1060
** or rely on spliturl if application/x-w..
1061
** [XXX] : this function sucks ! I don't parse bigger-than-body-size posts that
1062
** are partially stored in files, TODO ;)
1064
//#define post_heavy_debug
1065
//#define dummy_body_parse_debug
1066
void ngx_http_dummy_multipart_parse(ngx_http_request_ctx_t *ctx,
1067
ngx_http_request_t *r,
1071
ngx_str_t final_var, final_data;
1072
char *boundary, *varn_start, *varn_end;
1073
char *filen_start, *filen_end;
1074
char *end, *line_end;
1075
u_int boundary_len, varn_len, varc_len, idx;
1076
ngx_http_dummy_loc_conf_t *cf;
1077
ngx_http_dummy_main_conf_t *main_cf;
1079
cf = ngx_http_get_module_loc_conf(r, ngx_http_naxsi_module);
1080
main_cf = ngx_http_get_module_main_conf(r, ngx_http_naxsi_module);
1066
//#define post_heavy_debug
1067
//#define dummy_body_parse_debug
1068
void ngx_http_dummy_multipart_parse(ngx_http_request_ctx_t *ctx,
1069
ngx_http_request_t *r,
1073
ngx_str_t final_var, final_data;
1074
char *boundary, *varn_start, *varn_end;
1075
char *filen_start, *filen_end;
1076
char *end, *line_end;
1077
u_int boundary_len, varn_len, varc_len, idx;
1078
ngx_http_dummy_loc_conf_t *cf;
1079
ngx_http_dummy_main_conf_t *main_cf;
1081
cf = ngx_http_get_module_loc_conf(r, ngx_http_naxsi_module);
1082
main_cf = ngx_http_get_module_main_conf(r, ngx_http_naxsi_module);
1082
1084
#ifdef post_heavy_debug
1083
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1084
"XX-multipart/form-data");
1085
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1086
"XX-multipart/form-data");
1086
/* So far, I have noticed to correct ways of putting the boundary in a multipart post :
1087
** 1: in the content-type header, after multipart/form-data
1088
** 2: at the very begining of the body. */
1089
/*extract boundary*/
1090
boundary = ngx_strstr(src, "boundary=");
1092
boundary = ngx_strstr(r->headers_in.content_type->value.data, "boundary=");
1095
dummy_error_fatal(ctx, r, "no boundary present in POST data ?");
1098
boundary += 9; //strlen ("boundary=")
1099
boundary_len = strlen(boundary);
1088
/* So far, I have noticed to correct ways of putting the boundary in a multipart post :
1089
** 1: in the content-type header, after multipart/form-data
1090
** 2: at the very begining of the body. */
1091
/*extract boundary*/
1092
boundary = ngx_strstr(src, "boundary=");
1094
boundary = ngx_strstr(r->headers_in.content_type->value.data, "boundary=");
1097
dummy_error_fatal(ctx, r, "no boundary present in POST data ?");
1100
boundary += 9; //strlen ("boundary=")
1101
boundary_len = strlen(boundary);
1101
/* fetch every line starting with boundary */
1104
#ifdef post_heavy_debug
1105
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1106
"XX-POST data : (%s)", src+idx);
1108
//dummy_error_fatal(ctx, r, "POST data : (%s)", src+idx);
1109
/* if we've reached the last boundary '--' + boundary + '--' + '\r\n'*/
1110
if (idx+boundary_len+6 >= len)
1103
/* fetch every line starting with boundary */
1112
1106
#ifdef post_heavy_debug
1113
1107
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1114
"XX-reached end, not enough len");
1118
//check if line starts with -- (pre-boundary stuff)
1119
if (src[idx] != '-' || src[idx+1] != '-' ||
1120
//and if it's really followed by a boundary
1121
ngx_strncmp(src+idx+2, boundary, boundary_len) ||
1122
//and if it's not the last boundary of the buffer
1123
idx+boundary_len + 2 + 2 >= len ||
1124
//and if it's followed by \r\n
1125
src[idx+boundary_len+2] != '\r' || src[idx+boundary_len+3] != '\n') {
1127
dummy_error_fatal(ctx, r, "POST data is malformed (%s)", src+idx);
1130
idx += boundary_len + 4;
1131
/* we have two cases :
1133
** Content-Disposition: form-data; name="somename"; filename="NetworkManager.conf"\r\n
1134
** Content-Type: application/octet-stream\r\n\r\n
1136
** ---- normal post var
1137
** Content-Disposition: form-data; name="lastname"\r\n\r\n
1140
if (ngx_strncasecmp(src+idx,
1141
(u_char *) "content-disposition: form-data;", 30)) {
1142
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1143
"Unknown content-type: [%s]", src+idx);
1144
dummy_error_fatal(ctx, r, "POST data : unknown content-disposition");
1149
line_end = ngx_strchr(src+idx, '\n');
1151
dummy_error_fatal(ctx, r, "POST data : malformed boundary line");
1154
// seek for name="<var>" and filename="<var>" in the current line
1155
// verify that the name/filename tag founds are present
1156
varn_end = filen_end = NULL;
1157
varn_start = ngx_strstr(src+idx, "name=\"");
1158
if (varn_start && varn_start < line_end) {
1160
varn_end = ngx_strchr(varn_start, '"');
1164
filen_start = ngx_strstr(src+idx, "filename=\"");
1165
if (filen_start && filen_start < line_end) {
1167
/* avoid being bypassed by filenames like bla\"aa.php */
1168
filen_end = filen_start;
1170
filen_end = ngx_strchr(filen_end, '"');
1171
if (*(filen_end - 1) != '\\')
1174
} while (filen_end < line_end);
1175
/* here add support :
1176
** - when a file is here, the line bellow 'content-disposition' is content-type.
1177
** - skip this line. we should probably parse it ... to make regex on it :D
1179
line_end = ngx_strchr(line_end+1, '\n');
1181
dummy_error_fatal(ctx, r, "POST data : malformed 'filename' field");
1108
"XX-POST data : (%s)", src+idx);
1110
//dummy_error_fatal(ctx, r, "POST data : (%s)", src+idx);
1111
/* if we've reached the last boundary '--' + boundary + '--' + '\r\n'*/
1112
if (idx+boundary_len+6 >= len)
1114
#ifdef post_heavy_debug
1115
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1116
"XX-reached end, not enough len");
1120
//check if line starts with -- (pre-boundary stuff)
1121
if (src[idx] != '-' || src[idx+1] != '-' ||
1122
//and if it's really followed by a boundary
1123
ngx_strncmp(src+idx+2, boundary, boundary_len) ||
1124
//and if it's not the last boundary of the buffer
1125
idx+boundary_len + 2 + 2 >= len ||
1126
//and if it's followed by \r\n
1127
src[idx+boundary_len+2] != '\r' || src[idx+boundary_len+3] != '\n') {
1129
dummy_error_fatal(ctx, r, "POST data is malformed (%s)", src+idx);
1132
idx += boundary_len + 4;
1133
/* we have two cases :
1135
** Content-Disposition: form-data; name="somename"; filename="NetworkManager.conf"\r\n
1136
** Content-Type: application/octet-stream\r\n\r\n
1138
** ---- normal post var
1139
** Content-Disposition: form-data; name="lastname"\r\n\r\n
1142
if (ngx_strncasecmp(src+idx,
1143
(u_char *) "content-disposition: form-data;", 30)) {
1144
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1145
"Unknown content-type: [%s]", src+idx);
1146
dummy_error_fatal(ctx, r, "POST data : unknown content-disposition");
1151
line_end = ngx_strchr(src+idx, '\n');
1153
dummy_error_fatal(ctx, r, "POST data : malformed boundary line");
1156
// seek for name="<var>" and filename="<var>" in the current line
1157
// verify that the name/filename tag founds are present
1158
varn_end = filen_end = NULL;
1159
varn_start = ngx_strstr(src+idx, "name=\"");
1160
if (varn_start && varn_start < line_end) {
1162
varn_end = ngx_strchr(varn_start, '"');
1166
filen_start = ngx_strstr(src+idx, "filename=\"");
1167
if (filen_start && filen_start < line_end) {
1169
/* avoid being bypassed by filenames like bla\"aa.php */
1170
filen_end = filen_start;
1172
filen_end = ngx_strchr(filen_end, '"');
1173
if (*(filen_end - 1) != '\\')
1176
} while (filen_end < line_end);
1177
/* here add support :
1178
** - when a file is here, the line bellow 'content-disposition' is content-type.
1179
** - skip this line. we should probably parse it ... to make regex on it :D
1181
line_end = ngx_strchr(line_end+1, '\n');
1183
dummy_error_fatal(ctx, r, "POST data : malformed 'filename' field");
1188
// check that var name is present and not malformed
1189
if (!varn_start || !varn_end || varn_end <= varn_start) {
1190
dummy_error_fatal(ctx, r, "POST data : no 'name' in POST var");
1193
varn_len = varn_end - varn_start;
1194
// now idx point to the end of the
1195
// content-disposition: form-data; filename="" name=""
1196
idx += (u_char *)line_end - (src+idx) + 1;
1197
if (src[idx] != '\r' || src[idx+1] != '\n') {
1198
dummy_error_fatal(ctx, r, "POST data : malformed content-disposition line");
1202
// seek the end of the data too
1205
end = ngx_strstr(src+idx, "\r\n--");
1207
dummy_error_fatal(ctx, r, "POST data : malformed content-disposition line");
1210
if (!ngx_strncmp(end+4, boundary, boundary_len))
1213
idx += ((u_char *) end - (src+idx)) + 1;
1190
// check that var name is present and not malformed
1191
if (!varn_start || !varn_end || varn_end <= varn_start) {
1192
dummy_error_fatal(ctx, r, "POST data : no 'name' in POST var");
1195
varn_len = varn_end - varn_start;
1196
// now idx point to the end of the
1197
// content-disposition: form-data; filename="" name=""
1198
idx += (u_char *)line_end - (src+idx) + 1;
1199
if (src[idx] != '\r' || src[idx+1] != '\n') {
1200
dummy_error_fatal(ctx, r, "POST data : malformed content-disposition line");
1204
// seek the end of the data too
1218
dummy_error_fatal(ctx, r, "POST data : malformed line");
1222
final_var.data = (unsigned char *)varn_start;
1223
final_var.len = varn_len;
1224
final_data.data = (unsigned char *)filen_start;
1225
final_data.len = filen_end - filen_start;
1207
end = ngx_strstr(src+idx, "\r\n--");
1209
dummy_error_fatal(ctx, r, "POST data : malformed content-disposition line");
1212
if (!ngx_strncmp(end+4, boundary, boundary_len))
1215
idx += ((u_char *) end - (src+idx)) + 1;
1220
dummy_error_fatal(ctx, r, "POST data : malformed line");
1224
final_var.data = (unsigned char *)varn_start;
1225
final_var.len = varn_len;
1226
final_data.data = (unsigned char *)filen_start;
1227
final_data.len = filen_end - filen_start;
1226
1228
#ifdef post_heavy_debug
1227
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1228
"[POST] checking filename [%V] = [%V]",
1229
&final_var, &final_data);
1229
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1230
"[POST] checking filename [%V] = [%V]",
1231
&final_var, &final_data);
1231
/* here we got val name + val content !*/
1233
ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1234
cf->body_rules, r, ctx, FILE_EXT);
1233
/* here we got val name + val content !*/
1235
ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1236
cf->body_rules, r, ctx, FILE_EXT);
1235
1237
#ifdef post_heavy_debug
1237
/* here we got val name + val content !*/
1238
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1239
"No local body rules ?!");
1239
/* here we got val name + val content !*/
1240
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1241
"No local body rules ?!");
1242
if (main_cf->body_rules)
1243
ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1244
main_cf->body_rules, r, ctx, FILE_EXT);
1244
if (main_cf->body_rules)
1245
ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1246
main_cf->body_rules, r, ctx, FILE_EXT);
1245
1247
#ifdef post_heavy_debug
1247
/* here we got val name + val content !*/
1248
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1249
"No main body rules ?!");
1249
/* here we got val name + val content !*/
1250
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1251
"No main body rules ?!");
1252
idx += (u_char *) end - (src+idx);
1256
varc_len = (u_char *) end - (src+idx);
1257
final_var.data = (unsigned char *)varn_start;
1258
final_var.len = varn_len;
1259
final_data.data = src+idx;
1260
final_data.len = varc_len;
1261
#ifdef post_heavy_debug
1262
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1264
&final_var, &final_data);
1266
/* here we got val name + val content !*/
1268
ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1269
cf->body_rules, r, ctx, BODY);
1270
#ifdef post_heavy_debug
1254
idx += (u_char *) end - (src+idx);
1272
/* here we got val name + val content !*/
1273
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1274
"No local body rules ?!");
1258
varc_len = (u_char *) end - (src+idx);
1259
final_var.data = (unsigned char *)varn_start;
1260
final_var.len = varn_len;
1261
final_data.data = src+idx;
1262
final_data.len = varc_len;
1263
#ifdef post_heavy_debug
1264
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1266
&final_var, &final_data);
1268
/* here we got val name + val content !*/
1270
ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1271
cf->body_rules, r, ctx, BODY);
1272
#ifdef post_heavy_debug
1274
/* here we got val name + val content !*/
1275
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1276
"No local body rules ?!");
1277
if (main_cf->body_rules)
1278
ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1279
main_cf->body_rules, r, ctx, BODY);
1279
if (main_cf->body_rules)
1280
ngx_http_basestr_ruleset_n(r->pool, &final_var, &final_data,
1281
main_cf->body_rules, r, ctx, BODY);
1280
1282
#ifdef post_heavy_debug
1282
/* here we got val name + val content !*/
1283
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1284
"No main body rules ?!");
1284
/* here we got val name + val content !*/
1285
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1286
"No main body rules ?!");
1287
idx += (u_char *) end - (src+idx);
1290
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1294
if (!ngx_strncmp(end, "\r\n", 2))
1297
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1298
"(multipart) : OVER");
1302
//#define dummy_body_parse_debug
1305
ngx_http_dummy_body_parse(ngx_http_request_ctx_t *ctx,
1306
ngx_http_request_t *r,
1307
ngx_http_dummy_loc_conf_t *cf,
1308
ngx_http_dummy_main_conf_t *main_cf)
1314
u_int full_body_len;
1317
#ifdef dummy_body_parse_debug
1318
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1321
if (!r->request_body->bufs || !r->headers_in.content_type) {
1322
#ifdef dummy_body_parse_debug
1323
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1324
"XX-No content type ..");
1326
if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1327
ctx->weird_request = 1;
1331
if (r->request_body->temp_file) {
1332
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1333
"naxsi: POST REQUEST to temp_file, partially parsed.");
1334
if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__big_request, NULL, BODY, 0) == 0)
1335
ctx->big_request = 1;
1339
#ifdef dummy_body_parse_debug
1340
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1343
/* request body in single buffer */
1344
if (r->request_body->bufs->next == NULL) {
1345
full_body_len = (u_int) (r->request_body->bufs->buf->last -
1346
r->request_body->bufs->buf->pos);
1347
full_body = ngx_pcalloc(r->pool, (u_int) (full_body_len+1));
1348
memcpy(full_body, r->request_body->bufs->buf->pos, full_body_len);
1350
/* request body in chain */
1352
#ifdef dummy_body_parse_debug
1353
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1354
"[POST] REQUEST BODY IN CHAIN !");
1356
for (full_body_len = 0, bb = r->request_body->bufs; bb; bb = bb->next)
1357
full_body_len += (bb->buf->last - bb->buf->pos);
1358
full_body = ngx_pcalloc(r->pool, full_body_len+1);
1362
for(bb = r->request_body->bufs ; bb ; bb = bb->next)
1363
full_body = ngx_cpymem(full_body, bb->buf->pos,
1364
bb->buf->last - bb->buf->pos);
1366
#ifdef dummy_body_parse_debug
1367
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1368
"[POST] REQUEST BODY IN CHAIN [%s] (len=%d)",
1369
full_body, full_body_len);
1372
#ifdef dummy_body_parse_debug
1373
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1374
"content-len header (%d) mismatch actual len (%d) ??",
1375
r->headers_in.content_length_n, full_body_len);
1377
/* File probably got buffered. */
1378
if (r->headers_in.content_length_n != full_body_len) {
1379
if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1380
ctx->weird_request = 1;
1383
/* x-www-form-urlencoded POSTs */
1384
//33 = echo -n "application/x-www-form-urlencoded" | wc -c
1385
if (!ngx_strncasecmp(r->headers_in.content_type->value.data,
1386
(u_char *)"application/x-www-form-urlencoded", 33)) {
1387
#ifdef post_heavy_debug
1388
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1389
"XX-application/x-www..");
1391
tmp.len = full_body_len;
1392
tmp.data = full_body;
1394
#ifdef post_heavy_debug
1395
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1396
"XX-POST DATA [%V]", &tmp);
1398
if(ngx_http_spliturl_ruleset(r->pool, (char *)tmp.data,
1399
cf->body_rules, main_cf->body_rules,
1401
#ifdef post_heavy_debug
1402
dummy_error_fatal(ctx, r, "spliturl failed, someone is trying to trick us");
1404
if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1405
ctx->weird_request = 1;
1409
//19 = echo -n "multipart/form-data" | wc -c
1410
else if (!ngx_strncasecmp(r->headers_in.content_type->value.data,
1411
(u_char *) "multipart/form-data", 19)) {
1412
ngx_http_dummy_multipart_parse(ctx, r, full_body, full_body_len);
1415
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1416
"[POST] Unknown content-type, gtfo");
1417
if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1418
ctx->weird_request = 1;
1425
** does : bui ! this is a 'main' function, all the stuff goes from here.
1426
** to make it short, it does the following :
1427
** - if we got header rules, apply header_rules on each.
1428
** - apply generic_rules on url decoded URI.
1429
** - if we got get_rules and get args, apply get_rules varname/value couple.
1430
** - if we are in a POST/PUT request and we got body_rules, apply rules :)
1433
ngx_http_dummy_uri_parse(ngx_http_dummy_main_conf_t *main_cf,
1434
ngx_http_dummy_loc_conf_t *cf,
1435
ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
1437
ngx_str_t tmp, name;
1441
if (ctx->block && !cf->learning)
1443
if (!main_cf->generic_rules && !cf->generic_rules) {
1444
dummy_error_fatal(ctx, r, "no generic rules ?!");
1447
tmp.len = r->uri.len;
1448
tmp.data = ngx_pcalloc(r->pool, r->uri.len+1);
1450
dummy_error_fatal(ctx, r, "failed alloc of %d", r->uri.len+1);
1453
memcpy(tmp.data, r->uri.data, r->uri.len);
1456
if (cf->generic_rules)
1457
ngx_http_basestr_ruleset_n(r->pool, &name, &tmp, cf->generic_rules,
1459
if (main_cf->generic_rules)
1460
ngx_http_basestr_ruleset_n(r->pool, &name, &tmp, main_cf->generic_rules,
1462
ngx_pfree(r->pool, tmp.data);
1466
ngx_http_dummy_args_parse(ngx_http_dummy_main_conf_t *main_cf,
1467
ngx_http_dummy_loc_conf_t *cf,
1468
ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
1472
if (ctx->block && !cf->learning)
1476
if (!cf->get_rules && !main_cf->get_rules)
1478
tmp.len = r->args.len;
1479
tmp.data = ngx_pcalloc(r->pool, r->args.len+1);
1481
dummy_error_fatal(ctx, r, "failed alloc");
1484
memcpy(tmp.data, r->args.data, r->args.len);
1485
if(ngx_http_spliturl_ruleset(r->pool, (char *)tmp.data,
1486
cf->get_rules, main_cf->get_rules, r,
1488
dummy_error_fatal(ctx, r,
1489
"spliturl error : malformed url, possible attack");
1492
ngx_pfree(r->pool, tmp.data);
1496
ngx_http_dummy_headers_parse(ngx_http_dummy_main_conf_t *main_cf,
1497
ngx_http_dummy_loc_conf_t *cf,
1498
ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
1500
ngx_list_part_t *part;
1504
if (!cf->header_rules && !main_cf->header_rules)
1506
// this check may be removed, as it shouldn't be needed anymore !
1507
if (ctx->block && !cf->learning)
1509
part = &r->headers_in.headers.part;
1511
// this check may be removed, as it shouldn't be needed anymore !
1512
for (i = 0; !ctx->block ; i++) {
1513
if (i >= part->nelts) {
1514
if (part->next == NULL)
1289
idx += (u_char *) end - (src+idx);
1292
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1296
if (!ngx_strncmp(end, "\r\n", 2))
1299
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1300
"(multipart) : OVER");
1304
//#define dummy_body_parse_debug
1307
ngx_http_dummy_body_parse(ngx_http_request_ctx_t *ctx,
1308
ngx_http_request_t *r,
1309
ngx_http_dummy_loc_conf_t *cf,
1310
ngx_http_dummy_main_conf_t *main_cf)
1316
u_int full_body_len;
1319
#ifdef dummy_body_parse_debug
1320
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1323
if (!r->request_body->bufs || !r->headers_in.content_type) {
1324
#ifdef dummy_body_parse_debug
1325
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1326
"XX-No content type ..");
1328
if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1329
ctx->weird_request = 1;
1333
if (r->request_body->temp_file) {
1334
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1335
"naxsi: POST REQUEST to temp_file, partially parsed.");
1336
if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__big_request, NULL, BODY, 0) == 0)
1337
ctx->big_request = 1;
1341
#ifdef dummy_body_parse_debug
1342
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1345
/* request body in single buffer */
1346
if (r->request_body->bufs->next == NULL) {
1347
full_body_len = (u_int) (r->request_body->bufs->buf->last -
1348
r->request_body->bufs->buf->pos);
1349
full_body = ngx_pcalloc(r->pool, (u_int) (full_body_len+1));
1350
memcpy(full_body, r->request_body->bufs->buf->pos, full_body_len);
1352
/* request body in chain */
1354
#ifdef dummy_body_parse_debug
1355
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1356
"[POST] REQUEST BODY IN CHAIN !");
1358
for (full_body_len = 0, bb = r->request_body->bufs; bb; bb = bb->next)
1359
full_body_len += (bb->buf->last - bb->buf->pos);
1360
full_body = ngx_pcalloc(r->pool, full_body_len+1);
1364
for(bb = r->request_body->bufs ; bb ; bb = bb->next)
1365
full_body = ngx_cpymem(full_body, bb->buf->pos,
1366
bb->buf->last - bb->buf->pos);
1368
#ifdef dummy_body_parse_debug
1369
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1370
"[POST] REQUEST BODY IN CHAIN [%s] (len=%d)",
1371
full_body, full_body_len);
1374
#ifdef dummy_body_parse_debug
1375
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1376
"content-len header (%d) mismatch actual len (%d) ??",
1377
r->headers_in.content_length_n, full_body_len);
1379
/* File probably got buffered. */
1380
if (r->headers_in.content_length_n != full_body_len) {
1381
if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1382
ctx->weird_request = 1;
1385
/* x-www-form-urlencoded POSTs */
1386
//33 = echo -n "application/x-www-form-urlencoded" | wc -c
1387
if (!ngx_strncasecmp(r->headers_in.content_type->value.data,
1388
(u_char *)"application/x-www-form-urlencoded", 33)) {
1389
#ifdef post_heavy_debug
1390
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1391
"XX-application/x-www..");
1393
tmp.len = full_body_len;
1394
tmp.data = full_body;
1396
#ifdef post_heavy_debug
1397
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1398
"XX-POST DATA [%V]", &tmp);
1400
if(ngx_http_spliturl_ruleset(r->pool, (char *)tmp.data,
1401
cf->body_rules, main_cf->body_rules,
1403
#ifdef post_heavy_debug
1404
dummy_error_fatal(ctx, r, "spliturl failed, someone is trying to trick us");
1406
if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1407
ctx->weird_request = 1;
1411
//19 = echo -n "multipart/form-data" | wc -c
1412
else if (!ngx_strncasecmp(r->headers_in.content_type->value.data,
1413
(u_char *) "multipart/form-data", 19)) {
1414
ngx_http_dummy_multipart_parse(ctx, r, full_body, full_body_len);
1417
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1418
"[POST] Unknown content-type, gtfo");
1419
if (ngx_http_dummy_is_rule_whitelisted_n(r, cf, &nx_int__weird_request, NULL, BODY, 0) == 0)
1420
ctx->weird_request = 1;
1427
** does : bui ! this is a 'main' function, all the stuff goes from here.
1428
** to make it short, it does the following :
1429
** - if we got header rules, apply header_rules on each.
1430
** - apply generic_rules on url decoded URI.
1431
** - if we got get_rules and get args, apply get_rules varname/value couple.
1432
** - if we are in a POST/PUT request and we got body_rules, apply rules :)
1435
ngx_http_dummy_uri_parse(ngx_http_dummy_main_conf_t *main_cf,
1436
ngx_http_dummy_loc_conf_t *cf,
1437
ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
1439
ngx_str_t tmp, name;
1443
if (ctx->block && !cf->learning)
1445
if (!main_cf->generic_rules && !cf->generic_rules) {
1446
dummy_error_fatal(ctx, r, "no generic rules ?!");
1449
tmp.len = r->uri.len;
1450
tmp.data = ngx_pcalloc(r->pool, r->uri.len+1);
1452
dummy_error_fatal(ctx, r, "failed alloc of %d", r->uri.len+1);
1455
memcpy(tmp.data, r->uri.data, r->uri.len);
1458
if (cf->generic_rules)
1459
ngx_http_basestr_ruleset_n(r->pool, &name, &tmp, cf->generic_rules,
1461
if (main_cf->generic_rules)
1462
ngx_http_basestr_ruleset_n(r->pool, &name, &tmp, main_cf->generic_rules,
1464
ngx_pfree(r->pool, tmp.data);
1468
ngx_http_dummy_args_parse(ngx_http_dummy_main_conf_t *main_cf,
1469
ngx_http_dummy_loc_conf_t *cf,
1470
ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
1474
if (ctx->block && !cf->learning)
1478
if (!cf->get_rules && !main_cf->get_rules)
1480
tmp.len = r->args.len;
1481
tmp.data = ngx_pcalloc(r->pool, r->args.len+1);
1483
dummy_error_fatal(ctx, r, "failed alloc");
1486
memcpy(tmp.data, r->args.data, r->args.len);
1487
if(ngx_http_spliturl_ruleset(r->pool, (char *)tmp.data,
1488
cf->get_rules, main_cf->get_rules, r,
1490
dummy_error_fatal(ctx, r,
1491
"spliturl error : malformed url, possible attack");
1494
ngx_pfree(r->pool, tmp.data);
1498
ngx_http_dummy_headers_parse(ngx_http_dummy_main_conf_t *main_cf,
1499
ngx_http_dummy_loc_conf_t *cf,
1500
ngx_http_request_ctx_t *ctx, ngx_http_request_t *r)
1502
ngx_list_part_t *part;
1506
if (!cf->header_rules && !main_cf->header_rules)
1508
// this check may be removed, as it shouldn't be needed anymore !
1509
if (ctx->block && !cf->learning)
1511
part = &r->headers_in.headers.part;
1517
1512
h = part->elts;
1520
if (cf->header_rules)
1521
ngx_http_basestr_ruleset_n(r->pool, &(h[i].key), &(h[i].value),
1522
cf->header_rules, r, ctx, HEADERS);
1523
if (main_cf->header_rules)
1524
ngx_http_basestr_ruleset_n(r->pool, &(h[i].key), &(h[i].value),
1525
main_cf->header_rules, r, ctx, HEADERS);
1531
ngx_http_dummy_data_parse(ngx_http_request_ctx_t *ctx,
1532
ngx_http_request_t *r)
1534
ngx_http_dummy_loc_conf_t *cf;
1535
ngx_http_dummy_main_conf_t *main_cf;
1536
ngx_http_core_main_conf_t *cmcf;
1538
cf = ngx_http_get_module_loc_conf(r, ngx_http_naxsi_module);
1539
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
1540
main_cf = ngx_http_get_module_main_conf(r, ngx_http_naxsi_module);
1541
if (!cf || !ctx || !cmcf) {
1542
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1543
"XX-UNABLE TO PARSE IN DATA PARSE !!");
1546
/* process rules only if request is not already blocked or if
1547
the learning mode is enabled */
1548
ngx_http_dummy_headers_parse(main_cf, cf, ctx, r);
1550
ngx_http_dummy_uri_parse(main_cf, cf, ctx, r);
1552
ngx_http_dummy_args_parse(main_cf, cf, ctx, r);
1554
if ((r->method == NGX_HTTP_POST || r->method == NGX_HTTP_PUT) &&
1555
//presence of body rules (POST/PUT rules)
1556
(cf->body_rules || main_cf->body_rules) &&
1557
//and the presence of data to parse
1558
r->request_body && (!ctx->block || cf->learning))
1559
ngx_http_dummy_body_parse(ctx, r, cf, main_cf);
1560
ngx_http_dummy_update_current_ctx_status(ctx, cf, r);
1565
//#define custom_score_debug
1567
ngx_http_dummy_update_current_ctx_status(ngx_http_request_ctx_t *ctx,
1568
ngx_http_dummy_loc_conf_t *cf,
1569
ngx_http_request_t *r)
1571
unsigned int i, z, matched;
1572
ngx_http_check_rule_t *cr;
1573
ngx_http_special_score_t *sc;
1574
/* ngx_http_whitelist_rule_t *b; */
1575
/* //ngx_http_whitelist_location_t *cl; */
1577
//ngx_int_t *tmp_ptr;
1579
#ifdef custom_score_debug
1580
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1581
"XX-custom check rules");
1583
/* /\* check flags : as current_ctx_status updates status regarding flags (weird_request, big_body etc.) we need */
1584
/* to check first if those flags are whitelisted for this URL. *\/ */
1585
/* if (cf->wlr_url_hash && cf->wlr_url_hash->size) { */
1586
/* /\* check if the rule was not whitelisted *\/ */
1587
/* k = ngx_hash_key_lc(r->uri.data, r->uri.len); */
1588
/* b = (ngx_http_whitelist_rule_t*) ngx_hash_find(cf->wlr_url_hash, k, */
1589
/* (u_char*) r->uri.data, */
1592
/* #ifdef custom_score_debug */
1593
/* ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, */
1594
/* "XX-URL has whitelist, %d items", b->whitelist_locations->nelts); */
1596
/* for (i = 0; i < b->ids->nelts; i++) { */
1598
/* if (ctx->weird_request && */
1599
/* ((int *)b->ids->elts)[i] == WEIRD_REQUEST_INTERNAL_RULE_ID) { */
1600
/* #ifdef custom_score_debug */
1601
/* ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, */
1602
/* "XX-MATCH WHITELIST !"); */
1604
/* ctx->weird_request = 0; */
1606
/* if (ctx->big_request && */
1607
/* ((int *)b->ids->elts)[i] == BIG_BODY_INTERNAL_RULE_ID) { */
1608
/* #ifdef custom_score_debug */
1609
/* ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, */
1610
/* "XX-MATCH WHITELIST !"); */
1612
/* ctx->big_request = 0; */
1617
if (ctx->weird_request) {
1618
#ifdef custom_score_debug
1619
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1620
"XX-blocking, weird_request flag set");
1624
if (ctx->big_request) {
1625
#ifdef custom_score_debug
1626
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1627
"XX-blocking unexpected big request");
1632
if (cf->check_rules && ctx->special_scores) {
1633
#ifdef custom_score_debug
1634
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1635
"XX-we have custom check rules and CTX got special score :)");
1637
cr = cf->check_rules->elts;
1638
sc = ctx->special_scores->elts;
1639
for (z = 0; z < ctx->special_scores->nelts; z++)
1640
for (i = 0; i < cf->check_rules->nelts; i++) {
1641
#ifdef custom_score_debug
1642
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1643
"XX- rule says :(%s:%d) vs current context:(%s:%d) (flag=%d)",
1644
cr[i].sc_tag.data, cr[i].sc_score,
1645
sc[z].sc_tag->data, sc[z].sc_score, cr[i].cmp);
1647
if (!ngx_strcmp(sc[z].sc_tag->data, cr[i].sc_tag.data)) {
1513
// this check may be removed, as it shouldn't be needed anymore !
1514
for (i = 0; !ctx->block ; i++) {
1515
if (i >= part->nelts) {
1516
if (part->next == NULL)
1522
if (cf->header_rules)
1523
ngx_http_basestr_ruleset_n(r->pool, &(h[i].key), &(h[i].value),
1524
cf->header_rules, r, ctx, HEADERS);
1525
if (main_cf->header_rules)
1526
ngx_http_basestr_ruleset_n(r->pool, &(h[i].key), &(h[i].value),
1527
main_cf->header_rules, r, ctx, HEADERS);
1533
ngx_http_dummy_data_parse(ngx_http_request_ctx_t *ctx,
1534
ngx_http_request_t *r)
1536
ngx_http_dummy_loc_conf_t *cf;
1537
ngx_http_dummy_main_conf_t *main_cf;
1538
ngx_http_core_main_conf_t *cmcf;
1540
cf = ngx_http_get_module_loc_conf(r, ngx_http_naxsi_module);
1541
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
1542
main_cf = ngx_http_get_module_main_conf(r, ngx_http_naxsi_module);
1543
if (!cf || !ctx || !cmcf) {
1544
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1545
"XX-UNABLE TO PARSE IN DATA PARSE !!");
1548
/* process rules only if request is not already blocked or if
1549
the learning mode is enabled */
1550
ngx_http_dummy_headers_parse(main_cf, cf, ctx, r);
1552
ngx_http_dummy_uri_parse(main_cf, cf, ctx, r);
1554
ngx_http_dummy_args_parse(main_cf, cf, ctx, r);
1556
if ((r->method == NGX_HTTP_POST || r->method == NGX_HTTP_PUT) &&
1557
//presence of body rules (POST/PUT rules)
1558
(cf->body_rules || main_cf->body_rules) &&
1559
//and the presence of data to parse
1560
r->request_body && (!ctx->block || cf->learning))
1561
ngx_http_dummy_body_parse(ctx, r, cf, main_cf);
1562
ngx_http_dummy_update_current_ctx_status(ctx, cf, r);
1567
//#define custom_score_debug
1569
ngx_http_dummy_update_current_ctx_status(ngx_http_request_ctx_t *ctx,
1570
ngx_http_dummy_loc_conf_t *cf,
1571
ngx_http_request_t *r)
1573
unsigned int i, z, matched;
1574
ngx_http_check_rule_t *cr;
1575
ngx_http_special_score_t *sc;
1576
/* ngx_http_whitelist_rule_t *b; */
1577
/* //ngx_http_whitelist_location_t *cl; */
1579
//ngx_int_t *tmp_ptr;
1581
#ifdef custom_score_debug
1582
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1583
"XX-custom check rules");
1585
if (ctx->weird_request) {
1586
#ifdef custom_score_debug
1587
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1588
"XX-blocking, weird_request flag set");
1592
if (ctx->big_request) {
1593
#ifdef custom_score_debug
1594
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1595
"XX-blocking unexpected big request");
1600
if (cf->check_rules && ctx->special_scores) {
1601
#ifdef custom_score_debug
1602
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1603
"XX-we have custom check rules and CTX got special score :)");
1605
cr = cf->check_rules->elts;
1606
sc = ctx->special_scores->elts;
1607
for (z = 0; z < ctx->special_scores->nelts; z++)
1608
for (i = 0; i < cf->check_rules->nelts; i++) {
1648
1609
#ifdef custom_score_debug
1649
1610
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1650
1611
"XX- rule says :(%s:%d) vs current context:(%s:%d) (flag=%d)",
1651
1612
cr[i].sc_tag.data, cr[i].sc_score,
1652
1613
sc[z].sc_tag->data, sc[z].sc_score, cr[i].cmp);
1655
// huglier than your mom :)
1656
switch (cr[i].cmp) {
1658
matched = sc[z].sc_score > cr[i].sc_score ? 1 : 0;
1661
matched = sc[z].sc_score >= cr[i].sc_score ? 1 : 0;
1664
matched = sc[z].sc_score < cr[i].sc_score ? 1 : 0;
1667
matched = sc[z].sc_score <= cr[i].sc_score ? 1 : 0;
1615
if (!ngx_strcmp(sc[z].sc_tag->data, cr[i].sc_tag.data)) {
1671
1616
#ifdef custom_score_debug
1672
1617
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1673
"XX- custom score rule triggered ..");
1618
"XX- rule says :(%s:%d) vs current context:(%s:%d) (flag=%d)",
1619
cr[i].sc_tag.data, cr[i].sc_score,
1620
sc[z].sc_tag->data, sc[z].sc_score, cr[i].cmp);
1623
// huglier than your mom :)
1624
switch (cr[i].cmp) {
1626
matched = sc[z].sc_score > cr[i].sc_score ? 1 : 0;
1629
matched = sc[z].sc_score >= cr[i].sc_score ? 1 : 0;
1632
matched = sc[z].sc_score < cr[i].sc_score ? 1 : 0;
1635
matched = sc[z].sc_score <= cr[i].sc_score ? 1 : 0;
1639
#ifdef custom_score_debug
1640
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1641
"XX- custom score rule triggered ..");
1688
** This function is called when the body is read.
1689
** Will set-up flags to tell that parsing can be done,
1690
** and then run the core phases again
1691
** (WARNING: check backward compatibility of count--
1692
** with older version of nginx 0.7.x)
1694
//#define payload_handler_debug
1696
ngx_http_dummy_payload_handler(ngx_http_request_t *r) {
1697
ngx_http_request_ctx_t *ctx;
1698
ctx = ngx_http_get_module_ctx(r, ngx_http_naxsi_module);
1701
#ifdef payload_handler_debug
1702
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1703
"XX-dummy PAYLOAD HANDLER !");
1705
if (ctx->wait_for_body) {
1656
** This function is called when the body is read.
1657
** Will set-up flags to tell that parsing can be done,
1658
** and then run the core phases again
1659
** (WARNING: check backward compatibility of count--
1660
** with older version of nginx 0.7.x)
1662
//#define payload_handler_debug
1664
ngx_http_dummy_payload_handler(ngx_http_request_t *r) {
1665
ngx_http_request_ctx_t *ctx;
1666
ctx = ngx_http_get_module_ctx(r, ngx_http_naxsi_module);
1706
1669
#ifdef payload_handler_debug
1707
1670
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1708
"XX-dummy : AFTER NGX_AGAIN");
1710
ctx->wait_for_body = 0;
1711
ngx_http_core_run_phases(r);
1671
"XX-dummy PAYLOAD HANDLER !");
1673
if (ctx->wait_for_body) {
1674
#ifdef payload_handler_debug
1675
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1676
"XX-dummy : AFTER NGX_AGAIN");
1678
ctx->wait_for_body = 0;
1679
ngx_http_core_run_phases(r);