From bb9021da3ab551fe8c96547e3d6979d986699c90 Mon Sep 17 00:00:00 2001 From: Max Leske Date: Thu, 9 May 2024 18:48:10 +0200 Subject: [PATCH] fix: add missing JSON Content-Type rule The new modsecurity.conf file was missing rule 200001, which enables body processing of `application/json`. Also took the opportunity to put the content of the file into a form that is easier to maintain w.r.t. to changes from upstream. Fixes #252 --- src/etc/modsecurity.d/modsecurity.conf | 67 ++++++++++++++------------ 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/src/etc/modsecurity.d/modsecurity.conf b/src/etc/modsecurity.d/modsecurity.conf index 42de40c..682924d 100644 --- a/src/etc/modsecurity.d/modsecurity.conf +++ b/src/etc/modsecurity.d/modsecurity.conf @@ -1,53 +1,52 @@ # Original of the latest recommended version: # https://github.com/owasp-modsecurity/ModSecurity/blob/v3/master/modsecurity.conf-recommended -SecArgumentSeparator ${MODSEC_ARGUMENT_SEPARATOR} +# Directives configured upstream (in the same order) +SecRuleEngine ${MODSEC_RULE_ENGINE} +SecRequestBodyAccess ${MODSEC_REQ_BODY_ACCESS} +SecRequestBodyLimit ${MODSEC_REQ_BODY_LIMIT} +SecRequestBodyNoFilesLimit ${MODSEC_REQ_BODY_NOFILES_LIMIT} +SecRequestBodyLimitAction ${MODSEC_REQ_BODY_LIMIT_ACTION} +SecRequestBodyJsonDepthLimit ${MODSEC_REQ_BODY_JSON_DEPTH_LIMIT} SecArgumentsLimit ${MODSEC_ARGUMENTS_LIMIT} +SecPcreMatchLimit ${MODSEC_PCRE_MATCH_LIMIT} +SecPcreMatchLimitRecursion ${MODSEC_PCRE_MATCH_LIMIT_RECURSION} +SecResponseBodyAccess ${MODSEC_RESP_BODY_ACCESS} +SecResponseBodyMimeType ${MODSEC_RESP_BODY_MIMETYPE} +SecResponseBodyLimit ${MODSEC_RESP_BODY_LIMIT} +SecResponseBodyLimitAction ${MODSEC_RESP_BODY_LIMIT_ACTION} +SecTmpDir ${MODSEC_TMP_DIR} +SecDataDir ${MODSEC_DATA_DIR} SecAuditEngine ${MODSEC_AUDIT_ENGINE} -SecAuditLog ${MODSEC_AUDIT_LOG} -SecAuditLogFormat ${MODSEC_AUDIT_LOG_FORMAT} -SecAuditLogParts ${MODSEC_AUDIT_LOG_PARTS} SecAuditLogRelevantStatus "${MODSEC_AUDIT_LOG_RELEVANT_STATUS}" -SecAuditLogStorageDir ${MODSEC_AUDIT_STORAGE_DIR} +SecAuditLogParts ${MODSEC_AUDIT_LOG_PARTS} SecAuditLogType ${MODSEC_AUDIT_LOG_TYPE} +SecAuditLog ${MODSEC_AUDIT_LOG} +SecArgumentSeparator ${MODSEC_ARGUMENT_SEPARATOR} SecCookieFormat ${MODSEC_COOKIE_FORMAT} -SecDataDir ${MODSEC_DATA_DIR} +SecUnicodeMapFile unicode.mapping ${MODSEC_UNICODE_MAPPING} +SecStatusEngine ${MODSEC_STATUS_ENGINE} + +# Additional directives +SecAuditLogFormat ${MODSEC_AUDIT_LOG_FORMAT} +SecAuditLogStorageDir ${MODSEC_AUDIT_STORAGE_DIR} SecDebugLog ${MODSEC_DEBUG_LOG} SecDebugLogLevel ${MODSEC_DEBUG_LOGLEVEL} SecDisableBackendCompression ${MODSEC_DISABLE_BACKEND_COMPRESSION} -SecPcreMatchLimit ${MODSEC_PCRE_MATCH_LIMIT} -SecPcreMatchLimitRecursion ${MODSEC_PCRE_MATCH_LIMIT_RECURSION} -SecRequestBodyAccess ${MODSEC_REQ_BODY_ACCESS} -SecRequestBodyJsonDepthLimit ${MODSEC_REQ_BODY_JSON_DEPTH_LIMIT} -SecRequestBodyLimit ${MODSEC_REQ_BODY_LIMIT} -SecRequestBodyLimitAction ${MODSEC_REQ_BODY_LIMIT_ACTION} -SecRequestBodyNoFilesLimit ${MODSEC_REQ_BODY_NOFILES_LIMIT} -SecResponseBodyAccess ${MODSEC_RESP_BODY_ACCESS} -SecResponseBodyLimit ${MODSEC_RESP_BODY_LIMIT} -SecResponseBodyLimitAction ${MODSEC_RESP_BODY_LIMIT_ACTION} -SecResponseBodyMimeType ${MODSEC_RESP_BODY_MIMETYPE} -SecRuleEngine ${MODSEC_RULE_ENGINE} -SecStatusEngine ${MODSEC_STATUS_ENGINE} -SecTmpDir ${MODSEC_TMP_DIR} SecTmpSaveUploadedFiles ${MODSEC_TMP_SAVE_UPLOADED_FILES} -SecUnicodeMapFile unicode.mapping ${MODSEC_UNICODE_MAPPING} SecUploadDir ${MODSEC_UPLOAD_DIR} SecUploadFileMode ${MODSEC_UPLOAD_FILE_MODE} SecUploadKeepFiles ${MODSEC_UPLOAD_KEEP_FILES} -# Base SecRule configs +# Rules configured upstream (in the same order) +SecRule REQUEST_HEADERS:Content-Type "^(?:application(?:/soap\+|/)|text/)xml" \ + "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML" +SecRule REQUEST_HEADERS:Content-Type "^application/json" \ + "id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON" SecRule &ARGS "@ge 1000" \ "id:'200007', phase:2,t:none,log,deny,status:400,msg:'Failed to fully parse request body due to large argument count',severity:2" -SecRule MULTIPART_UNMATCHED_BOUNDARY "@eq 1" \ - "id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'" SecRule REQBODY_ERROR "!@eq 0" \ "id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2" -SecRule REQUEST_HEADERS:Content-Type "^(?:application(?:/soap\+|/)|text/)xml" \ - "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML" -SecRule REQUEST_HEADERS:Content-Type "^application/[a-z0-9.-]+[+]json" \ - "id:'200006',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON" -SecRule TX:/^MSC_/ "!@streq 0" \ - "id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'" SecRule MULTIPART_STRICT_ERROR "!@eq 0" \ "id:'200003',phase:2,t:none,log,deny,status:400, \ msg:'Multipart request body failed strict validation: \ @@ -63,3 +62,11 @@ SecRule MULTIPART_STRICT_ERROR "!@eq 0" \ IP %{MULTIPART_INVALID_PART}, \ IH %{MULTIPART_INVALID_HEADER_FOLDING}, \ FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'" +SecRule MULTIPART_UNMATCHED_BOUNDARY "@eq 1" \ + "id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'" +SecRule TX:/^MSC_/ "!@streq 0" \ + "id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'" + +# Additional rules +SecRule REQUEST_HEADERS:Content-Type "^application/[a-z0-9.-]+[+]json" \ + "id:'200006',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"