Adds support to SecResponseBodyMimeType

This commit is contained in:
Felipe Zimmerle
2015-12-24 11:53:43 -03:00
parent c2d9a153cb
commit decf04d264
7 changed files with 141 additions and 3 deletions

View File

@@ -105,6 +105,7 @@ Assay::Assay(ModSecurity *ms, Rules *rules, void *logCbData)
m_requestBodyType(UnknownFormat),
m_requestHeadersNames(NULL),
m_responseHeadersNames(NULL),
m_responseContentType(NULL),
m_marker(""),
start(cpu_seconds()),
m_logCbData(logCbData),
@@ -127,6 +128,10 @@ Assay::Assay(ModSecurity *ms, Rules *rules, void *logCbData)
m_collections.store("RESPONSE_HEADERS_NAMES", std::string(""));
this->m_responseHeadersNames = m_collections.resolveFirst(
"RESPONSE_HEADERS_NAMES");
m_collections.store("RESPONSE_CONTENT_TYPE", std::string(""));
this->m_responseContentType = m_collections.resolveFirst(
"RESPONSE_CONTENT_TYPE");
#ifndef NO_LOGS
this->debug(4, "Initialising transaction");
@@ -860,7 +865,7 @@ int Assay::addResponseHeader(const std::string& key,
this->m_collections.store("RESPONSE_HEADERS:" + key, value);
if (tolower(key) == "content-type") {
this->m_collections.store("RESPONSE_CONTENT_TYPE", value);
this->m_responseContentType->assign(value);
}
return 1;
}
@@ -951,6 +956,21 @@ int Assay::processResponseBody() {
return true;
}
std::set<std::string> &bi = this->m_rules->m_responseBodyTypeToBeInspected;
auto t = bi.find(*m_responseContentType);
if (t == bi.end() && bi.empty() == false) {
#ifndef NO_LOGS
debug(5, "Response Content-Type is " + *m_responseContentType + \
". It is not marked to be inspected.");
std::string validContetTypes("");
for (std::set<std::string>::iterator i = bi.begin();
i != bi.end(); i++) {
validContetTypes.append(*i + " ");
}
debug(8, "Content-Type(s) marked to be inspected: " + validContetTypes);
#endif
return true;
}
if (m_collections.resolveFirst("OUTBOUND_DATA_ERROR") == NULL) {
m_collections.store("OUTBOUND_DATA_ERROR", "0");
}
@@ -985,6 +1005,17 @@ int Assay::processResponseBody() {
int Assay::appendResponseBody(const unsigned char *buf, size_t len) {
int current_size = this->m_responseBody.tellp();
std::set<std::string> &bi = this->m_rules->m_responseBodyTypeToBeInspected;
auto t = bi.find(*m_responseContentType);
if (t == bi.end() && bi.empty() == false) {
#ifndef NO_LOGS
debug(4, "Not appending response body. " \
"Response Content-Type is " + *m_responseContentType + \
". It is not marked to be inspected.");
#endif
return true;
}
#ifndef NO_LOGS
debug(9, "Appending response body: " + std::to_string(len + current_size)
+ " bytes. Limit set to: " +

View File

@@ -8,7 +8,8 @@
%define parse.assert
%code requires
{
# include <string>
#include <string>
#include <iterator>
namespace ModSecurity {
namespace Parser {
@@ -601,6 +602,16 @@ expression:
| CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION
| CONFIG_DIR_PCRE_MATCH_LIMIT
| CONGIG_DIR_RESPONSE_BODY_MP
{
std::istringstream buf($1);
std::istream_iterator<std::string> beg(buf), end;
std::set<std::string> tokens(beg, end);
for (std::set<std::string>::iterator it=tokens.begin();
it!=tokens.end(); ++it)
{
driver.m_responseBodyTypeToBeInspected.insert(*it);
}
}
| CONGIG_DIR_SEC_TMP_DIR
| CONGIG_DIR_SEC_DATA_DIR
| CONGIG_DIR_SEC_ARG_SEP

View File

@@ -259,7 +259,7 @@ CONFIG_DIR_UNICODE_MAP_FILE (?i:SecUnicodeMapFile)
%{ /* Other configurations */ %}
{CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_PCRE_MATCH_LIMIT}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_PCRE_MATCH_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONGIG_DIR_RESPONSE_BODY_MP}[ ]{FREE_TEXT_NEW_LINE} { return yy::seclang_parser::make_CONGIG_DIR_RESPONSE_BODY_MP(yytext, *driver.loc.back()); }
{CONGIG_DIR_RESPONSE_BODY_MP}[ ]{FREE_TEXT_NEW_LINE} { return yy::seclang_parser::make_CONGIG_DIR_RESPONSE_BODY_MP(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONGIG_DIR_SEC_TMP_DIR}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONGIG_DIR_SEC_TMP_DIR(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONGIG_DIR_SEC_DATA_DIR}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONGIG_DIR_SEC_DATA_DIR(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONGIG_DIR_SEC_ARG_SEP}[ ]{FREE_TEXT_NEW_LINE} { return yy::seclang_parser::make_CONGIG_DIR_SEC_ARG_SEP(yytext, *driver.loc.back()); }

View File

@@ -221,6 +221,13 @@ int Rules::merge(Driver *from) {
this->requestBodyLimitAction = from->requestBodyLimitAction;
this->responseBodyLimitAction = from->responseBodyLimitAction;
for (std::set<std::string>::iterator
it=from->m_responseBodyTypeToBeInspected.begin();
it!=from->m_responseBodyTypeToBeInspected.end(); ++it)
{
m_responseBodyTypeToBeInspected.insert(*it);
}
/*
*
* default Actions is something per configuration context, there is