mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-10-01 12:07:46 +03:00
Adds support to MULTIPART_CRLF_LF_LINES variable
This commit is contained in:
@@ -431,6 +431,12 @@ int Assay::processRequestBody() {
|
|||||||
for (auto &a : m.variables) {
|
for (auto &a : m.variables) {
|
||||||
store_variable(a.first, a.second);
|
store_variable(a.first, a.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m.crlf && m.lf) {
|
||||||
|
store_variable("MULTIPART_CRLF_LF_LINES", "1");
|
||||||
|
} else {
|
||||||
|
store_variable("MULTIPART_CRLF_LF_LINES", "0");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -59,7 +59,7 @@ OPERATORNOARG (?i:@detectSQLi|@detectXSS|@geoLookup|@validateUrlEncoding|@valida
|
|||||||
|
|
||||||
TRANSFORMATION t:(lowercase|urlDecodeUni|urlDecode|none|compressWhitespace|removeWhitespace|replaceNulls|removeNulls|htmlEntityDecode|jsDecode|cssDecode|trim)
|
TRANSFORMATION t:(lowercase|urlDecodeUni|urlDecode|none|compressWhitespace|removeWhitespace|replaceNulls|removeNulls|htmlEntityDecode|jsDecode|cssDecode|trim)
|
||||||
|
|
||||||
VARIABLE (?i:MATCHED_VAR_NAME|MATCHED_VARS_NAMES|MATCHED_VAR|MATCHED_VARS|INBOUND_DATA_ERROR|FULL_REQUEST|FILES|AUTH_TYPE|ARGS_NAMES|ARGS|QUERY_STRING|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_COOKIES_NAMES|REQUEST_COOKIES|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_HEADERS|RESPONSE_PROTOCOL|RESPONSE_STATUS|TX|GEO)
|
VARIABLE (?i:MULTIPART_CRLF_LF_LINES|MATCHED_VAR_NAME|MATCHED_VARS_NAMES|MATCHED_VAR|MATCHED_VARS|INBOUND_DATA_ERROR|FULL_REQUEST|FILES|AUTH_TYPE|ARGS_NAMES|ARGS|QUERY_STRING|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_COOKIES_NAMES|REQUEST_COOKIES|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_HEADERS|RESPONSE_PROTOCOL|RESPONSE_STATUS|TX|GEO)
|
||||||
RUN_TIME_VAR_DUR (?i:DURATION)
|
RUN_TIME_VAR_DUR (?i:DURATION)
|
||||||
RUN_TIME_VAR_ENV (?i:ENV)
|
RUN_TIME_VAR_ENV (?i:ENV)
|
||||||
RUN_TIME_VAR_BLD (?i:MODSEC_BUILD)
|
RUN_TIME_VAR_BLD (?i:MODSEC_BUILD)
|
||||||
|
@@ -25,7 +25,9 @@ namespace ModSecurity {
|
|||||||
namespace RequestBodyProcessor {
|
namespace RequestBodyProcessor {
|
||||||
|
|
||||||
Multipart::Multipart(std:: string header)
|
Multipart::Multipart(std:: string header)
|
||||||
: m_boundaryStartsWithWhiteSpace(false),
|
: crlf(false),
|
||||||
|
lf(true),
|
||||||
|
m_boundaryStartsWithWhiteSpace(false),
|
||||||
m_boundaryIsQuoted(false),
|
m_boundaryIsQuoted(false),
|
||||||
m_header(header) {
|
m_header(header) {
|
||||||
}
|
}
|
||||||
@@ -184,6 +186,21 @@ bool Multipart::boundaryContainsOnlyValidCharacters() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Multipart::checkForCrlfLf(const std::string &data) {
|
||||||
|
size_t start = 0;
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
|
pos = data.find("\n", start);
|
||||||
|
while (pos != std::string::npos) {
|
||||||
|
if (pos > 1 && data.at(pos-1) == '\r') {
|
||||||
|
this->crlf = true;
|
||||||
|
} else {
|
||||||
|
this->lf = true;
|
||||||
|
}
|
||||||
|
pos = data.find("\n", pos + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Multipart::process(std::string data) {
|
bool Multipart::process(std::string data) {
|
||||||
std::list<std::string> blobs;
|
std::list<std::string> blobs;
|
||||||
size_t start = data.find(m_boundary);
|
size_t start = data.find(m_boundary);
|
||||||
@@ -201,6 +218,9 @@ bool Multipart::process(std::string data) {
|
|||||||
}
|
}
|
||||||
std::string block = std::string(data, start + m_boundary.length() +
|
std::string block = std::string(data, start + m_boundary.length() +
|
||||||
+ endl, end - (start + m_boundary.length() + endl) - endl);
|
+ endl, end - (start + m_boundary.length() + endl) - endl);
|
||||||
|
|
||||||
|
checkForCrlfLf(block);
|
||||||
|
|
||||||
blobs.push_back(block);
|
blobs.push_back(block);
|
||||||
start = end;
|
start = end;
|
||||||
}
|
}
|
||||||
|
@@ -33,8 +33,11 @@ class Multipart {
|
|||||||
bool boundaryContainsOnlyValidCharacters();
|
bool boundaryContainsOnlyValidCharacters();
|
||||||
bool conuntBoundaryParameters();
|
bool conuntBoundaryParameters();
|
||||||
bool process(std::string data);
|
bool process(std::string data);
|
||||||
|
void checkForCrlfLf(const std::string &blob);
|
||||||
|
|
||||||
ModSecurityStringVariables variables;
|
ModSecurityStringVariables variables;
|
||||||
|
bool crlf;
|
||||||
|
bool lf;
|
||||||
private:
|
private:
|
||||||
void debug(int a, std::string str) {
|
void debug(int a, std::string str) {
|
||||||
std::cout << "Debug: " << str << std::endl;
|
std::cout << "Debug: " << str << std::endl;
|
||||||
|
125
test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json
Normal file
125
test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"enabled":1,
|
||||||
|
"version_min":300000,
|
||||||
|
"title":"Testing Variables :: FILES (1/1)",
|
||||||
|
"client":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":123
|
||||||
|
},
|
||||||
|
"server":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":80
|
||||||
|
},
|
||||||
|
"request":{
|
||||||
|
"headers":{
|
||||||
|
"Host":"localhost",
|
||||||
|
"User-Agent":"curl/7.38.0",
|
||||||
|
"Accept":"*/*",
|
||||||
|
"Content-Length":"330",
|
||||||
|
"Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2",
|
||||||
|
"Expect":"100-continue"
|
||||||
|
},
|
||||||
|
"uri":"/",
|
||||||
|
"protocol":"POST",
|
||||||
|
"body":[
|
||||||
|
"--------------------------756b6d74fa1a8ee2",
|
||||||
|
"Content-Disposition: form-data; name=\"name\"",
|
||||||
|
"",
|
||||||
|
"test",
|
||||||
|
"--------------------------756b6d74fa1a8ee2",
|
||||||
|
"Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"",
|
||||||
|
"Content-Type: text/plain",
|
||||||
|
"",
|
||||||
|
"This is a very small test file..",
|
||||||
|
"--------------------------756b6d74fa1a8ee2",
|
||||||
|
"Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"",
|
||||||
|
"Content-Type: text/plain",
|
||||||
|
"",
|
||||||
|
"This is another very small test file..",
|
||||||
|
"--------------------------756b6d74fa1a8ee2--"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"response":{
|
||||||
|
"headers":{
|
||||||
|
"Date":"Mon, 13 Jul 2015 20:02:41 GMT",
|
||||||
|
"Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT",
|
||||||
|
"Content-Type":"text/html"
|
||||||
|
},
|
||||||
|
"body":[
|
||||||
|
"no need."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"expected":{
|
||||||
|
"debug_log":"Target value: \"0\" \\(Variable: MULTIPART_CRLF_LF_LINES\\)"
|
||||||
|
},
|
||||||
|
"rules":[
|
||||||
|
"SecRuleEngine On",
|
||||||
|
"SecDebugLog \/tmp\/modsec_debug.log",
|
||||||
|
"SecDebugLogLevel 9",
|
||||||
|
"SecRule MULTIPART_CRLF_LF_LINES \"@contains 0\" \"phase:3,pass,t:trim\""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enabled":1,
|
||||||
|
"version_min":300000,
|
||||||
|
"title":"Testing Variables :: FILES (1/1)",
|
||||||
|
"client":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":123
|
||||||
|
},
|
||||||
|
"server":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":80
|
||||||
|
},
|
||||||
|
"request":{
|
||||||
|
"headers":{
|
||||||
|
"Host":"localhost",
|
||||||
|
"User-Agent":"curl/7.38.0",
|
||||||
|
"Accept":"*/*",
|
||||||
|
"Content-Length":"330",
|
||||||
|
"Content-Type":"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2",
|
||||||
|
"Expect":"100-continue"
|
||||||
|
},
|
||||||
|
"uri":"/",
|
||||||
|
"protocol":"POST",
|
||||||
|
"body":[
|
||||||
|
"--------------------------756b6d74fa1a8ee2",
|
||||||
|
"Content-Disposition: form-data; name=\"name\"",
|
||||||
|
"",
|
||||||
|
"test",
|
||||||
|
"--------------------------756b6d74fa1a8ee2",
|
||||||
|
"Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"",
|
||||||
|
"Content-Type: text/plain",
|
||||||
|
"",
|
||||||
|
"This is a very small test file..",
|
||||||
|
"--------------------------756b6d74fa1a8ee2",
|
||||||
|
"Content-Disposition: form-data; name=\"filedata\"; filename=\"small_text_file.txt\"\r",
|
||||||
|
"Content-Type: text/plain\r",
|
||||||
|
"\r",
|
||||||
|
"This is another very small test file..\r",
|
||||||
|
"--------------------------756b6d74fa1a8ee2--\r"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"response":{
|
||||||
|
"headers":{
|
||||||
|
"Date":"Mon, 13 Jul 2015 20:02:41 GMT",
|
||||||
|
"Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT",
|
||||||
|
"Content-Type":"text/html"
|
||||||
|
},
|
||||||
|
"body":[
|
||||||
|
"no need."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"expected":{
|
||||||
|
"debug_log":"Target value: \"1\" \\(Variable: MULTIPART_CRLF_LF_LINES\\)"
|
||||||
|
},
|
||||||
|
"rules":[
|
||||||
|
"SecRuleEngine On",
|
||||||
|
"SecDebugLog \/tmp\/modsec_debug.log",
|
||||||
|
"SecDebugLogLevel 9",
|
||||||
|
"SecRule MULTIPART_CRLF_LF_LINES \"@contains 0\" \"phase:3,pass,t:trim\""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
Reference in New Issue
Block a user