Skip to content

Commit f5efd9a

Browse files
authored
Merge pull request #2686 from SpiderLabs/v3/dev/issue_2670_a
Support SecRequestBodyNoFilesLimit
2 parents 6bd1c77 + 4c526fc commit f5efd9a

File tree

3 files changed

+463
-38
lines changed

3 files changed

+463
-38
lines changed

headers/modsecurity/rules_set_properties.h

+1
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ class RulesSetProperties {
368368
to->m_argumentsLimit.merge(&from->m_argumentsLimit);
369369
to->m_requestBodyJsonDepthLimit.merge(&from->m_requestBodyJsonDepthLimit);
370370
to->m_requestBodyLimit.merge(&from->m_requestBodyLimit);
371+
to->m_requestBodyNoFilesLimit.merge(&from->m_requestBodyNoFilesLimit);
371372
to->m_responseBodyLimit.merge(&from->m_responseBodyLimit);
372373

373374
merge_bodylimitaction_value(to->m_requestBodyLimitAction,

src/transaction.cc

+70-38
Original file line numberDiff line numberDiff line change
@@ -804,25 +804,43 @@ int Transaction::processRequestBody() {
804804
*/
805805
std::unique_ptr<std::string> a = m_variableRequestHeaders.resolveFirst(
806806
"Content-Type");
807+
808+
bool requestBodyNoFilesLimitExceeded = false;
809+
if ((m_requestBodyType == WWWFormUrlEncoded) ||
810+
(m_requestBodyProcessor == JSONRequestBody) ||
811+
(m_requestBodyProcessor == XMLRequestBody)) {
812+
if ((m_rules->m_requestBodyNoFilesLimit.m_set)
813+
&& (m_requestBody.str().size() > m_rules->m_requestBodyNoFilesLimit.m_value)) {
814+
m_variableReqbodyError.set("1", 0);
815+
m_variableReqbodyErrorMsg.set("Request body excluding files is bigger than the maximum expected.", 0);
816+
m_variableInboundDataError.set("1", m_variableOffset);
817+
ms_dbg(5, "Request body excluding files is bigger than the maximum expected.");
818+
requestBodyNoFilesLimitExceeded = true;
819+
}
820+
}
821+
807822
#ifdef WITH_LIBXML2
808823
if (m_requestBodyProcessor == XMLRequestBody) {
809-
std::string error;
810-
if (m_xml->init() == true) {
811-
m_xml->processChunk(m_requestBody.str().c_str(),
812-
m_requestBody.str().size(),
813-
&error);
814-
m_xml->complete(&error);
815-
}
816-
if (error.empty() == false) {
817-
m_variableReqbodyError.set("1", m_variableOffset);
818-
m_variableReqbodyErrorMsg.set("XML parsing error: " + error,
819-
m_variableOffset);
820-
m_variableReqbodyProcessorErrorMsg.set("XML parsing error: " \
821-
+ error, m_variableOffset);
822-
m_variableReqbodyProcessorError.set("1", m_variableOffset);
823-
} else {
824-
m_variableReqbodyError.set("0", m_variableOffset);
825-
m_variableReqbodyProcessorError.set("0", m_variableOffset);
824+
// large size might cause issues in the parsing itself; omit if exceeded
825+
if (!requestBodyNoFilesLimitExceeded) {
826+
std::string error;
827+
if (m_xml->init() == true) {
828+
m_xml->processChunk(m_requestBody.str().c_str(),
829+
m_requestBody.str().size(),
830+
&error);
831+
m_xml->complete(&error);
832+
}
833+
if (error.empty() == false) {
834+
m_variableReqbodyError.set("1", m_variableOffset);
835+
m_variableReqbodyErrorMsg.set("XML parsing error: " + error,
836+
m_variableOffset);
837+
m_variableReqbodyProcessorErrorMsg.set("XML parsing error: " \
838+
+ error, m_variableOffset);
839+
m_variableReqbodyProcessorError.set("1", m_variableOffset);
840+
} else {
841+
m_variableReqbodyError.set("0", m_variableOffset);
842+
m_variableReqbodyProcessorError.set("0", m_variableOffset);
843+
}
826844
}
827845
#endif
828846
#if WITH_YAJL
@@ -831,26 +849,29 @@ int Transaction::processRequestBody() {
831849
#else
832850
if (m_requestBodyProcessor == JSONRequestBody) {
833851
#endif
834-
std::string error;
835-
if (m_rules->m_requestBodyJsonDepthLimit.m_set) {
836-
m_json->setMaxDepth(m_rules->m_requestBodyJsonDepthLimit.m_value);
837-
}
838-
if (m_json->init() == true) {
839-
m_json->processChunk(m_requestBody.str().c_str(),
840-
m_requestBody.str().size(),
841-
&error);
842-
m_json->complete(&error);
843-
}
844-
if (error.empty() == false && m_requestBody.str().size() > 0) {
845-
m_variableReqbodyError.set("1", m_variableOffset);
846-
m_variableReqbodyProcessorError.set("1", m_variableOffset);
847-
m_variableReqbodyErrorMsg.set("JSON parsing error: " + error,
848-
m_variableOffset);
849-
m_variableReqbodyProcessorErrorMsg.set("JSON parsing error: " \
850-
+ error, m_variableOffset);
851-
} else {
852-
m_variableReqbodyError.set("0", m_variableOffset);
853-
m_variableReqbodyProcessorError.set("0", m_variableOffset);
852+
// large size might cause issues in the parsing itself; omit if exceeded
853+
if (!requestBodyNoFilesLimitExceeded) {
854+
std::string error;
855+
if (m_rules->m_requestBodyJsonDepthLimit.m_set) {
856+
m_json->setMaxDepth(m_rules->m_requestBodyJsonDepthLimit.m_value);
857+
}
858+
if (m_json->init() == true) {
859+
m_json->processChunk(m_requestBody.str().c_str(),
860+
m_requestBody.str().size(),
861+
&error);
862+
m_json->complete(&error);
863+
}
864+
if (error.empty() == false && m_requestBody.str().size() > 0) {
865+
m_variableReqbodyError.set("1", m_variableOffset);
866+
m_variableReqbodyProcessorError.set("1", m_variableOffset);
867+
m_variableReqbodyErrorMsg.set("JSON parsing error: " + error,
868+
m_variableOffset);
869+
m_variableReqbodyProcessorErrorMsg.set("JSON parsing error: " \
870+
+ error, m_variableOffset);
871+
} else {
872+
m_variableReqbodyError.set("0", m_variableOffset);
873+
m_variableReqbodyProcessorError.set("0", m_variableOffset);
874+
}
854875
}
855876
#endif
856877
#if defined(WITH_LIBXML2) or defined(WITH_YAJL)
@@ -859,11 +880,13 @@ int Transaction::processRequestBody() {
859880
if (m_requestBodyType == MultiPartRequestBody) {
860881
#endif
861882
std::string error;
883+
int reqbodyNoFilesLength = 0;
862884
if (a != NULL) {
863885
Multipart m(*a, this);
864886
if (m.init(&error) == true) {
865887
m.process(m_requestBody.str(), &error, m_variableOffset);
866888
}
889+
reqbodyNoFilesLength = m.m_reqbody_no_files_length;
867890
m.multipart_complete(&error);
868891
}
869892
if (error.empty() == false) {
@@ -873,13 +896,22 @@ int Transaction::processRequestBody() {
873896
m_variableOffset);
874897
m_variableReqbodyProcessorErrorMsg.set("Multipart parsing " \
875898
"error: " + error, m_variableOffset);
899+
} else if (((m_rules->m_requestBodyNoFilesLimit.m_set)
900+
&& (reqbodyNoFilesLength > m_rules->m_requestBodyNoFilesLimit.m_value))) {
901+
m_variableReqbodyError.set("1", 0);
902+
m_variableReqbodyErrorMsg.set("Request body excluding files is bigger than the maximum expected.", 0);
903+
m_variableInboundDataError.set("1", m_variableOffset);
904+
ms_dbg(5, "Request body excluding files is bigger than the maximum expected.");
876905
} else {
877906
m_variableReqbodyError.set("0", m_variableOffset);
878907
m_variableReqbodyProcessorError.set("0", m_variableOffset);
879908
}
880909
} else if (m_requestBodyType == WWWFormUrlEncoded) {
881910
m_variableOffset++;
882-
extractArguments("POST", m_requestBody.str(), m_variableOffset);
911+
// large size might cause issues in the parsing itself; omit if exceeded
912+
if (!requestBodyNoFilesLimitExceeded) {
913+
extractArguments("POST", m_requestBody.str(), m_variableOffset);
914+
}
883915
} else if (m_requestBodyType != UnknownFormat) {
884916
/**
885917
* FIXME: double check to see if that is a valid scenario...

0 commit comments

Comments
 (0)