Skip to content

Commit f989ecd

Browse files
committed
Adds support to SecXMLExternalEntity
1 parent 6a7b970 commit f989ecd

File tree

13 files changed

+215
-30
lines changed

13 files changed

+215
-30
lines changed

headers/modsecurity/rules_properties.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class RulesProperties {
5656
requestBodyInMemoryLimit(0),
5757
secRequestBodyAccess(false),
5858
secResponseBodyAccess(false),
59+
secXMLExternalEntity(false),
5960
requestBodyLimitAction(ProcessPartialBodyLimitAction),
6061
responseBodyLimit(0),
6162
responseBodyLimitAction(ProcessPartialBodyLimitAction),
@@ -71,6 +72,7 @@ class RulesProperties {
7172
requestBodyInMemoryLimit(0),
7273
secRequestBodyAccess(false),
7374
secResponseBodyAccess(false),
75+
secXMLExternalEntity(false),
7476
requestBodyLimitAction(ProcessPartialBodyLimitAction),
7577
responseBodyLimit(0),
7678
responseBodyLimitAction(ProcessPartialBodyLimitAction),
@@ -202,6 +204,7 @@ class RulesProperties {
202204

203205
bool secRequestBodyAccess;
204206
bool secResponseBodyAccess;
207+
bool secXMLExternalEntity;
205208
std::string audit_log_path;
206209
std::string audit_log_parts;
207210
std::list<std::string> components;

src/actions/ctl_request_body_processor_xml.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ namespace modsecurity {
2424
namespace actions {
2525

2626

27-
bool CtlRequestBodyProcessorXML::evaluate(Rule *rule, Transaction *transaction) {
28-
transaction->m_requestBodyProcessor = modsecurity::Transaction::XMLRequestBody;
27+
bool CtlRequestBodyProcessorXML::evaluate(Rule *rule,
28+
Transaction *transaction) {
29+
transaction->m_requestBodyProcessor = Transaction::XMLRequestBody;
2930
return true;
3031
}
3132

src/operators/validate_dtd.cc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,21 @@ bool ValidateDTD::init(const std::string &file, const char **error) {
3939
xmlSetGenericErrorFunc(NULL,
4040
null_error);
4141

42-
m_dtd = xmlParseDTD(NULL, (const xmlChar *)m_resource.c_str());
43-
if (m_dtd == NULL) {
44-
std::string err = std::string("XML: Failed to load DTD: ") \
45-
+ m_resource;
46-
*error = strdup(err.c_str());
47-
return false;
48-
}
49-
5042
return true;
5143
}
5244

5345

5446
bool ValidateDTD::evaluate(Transaction *t, const std::string &str) {
5547
xmlValidCtxtPtr cvp;
5648

49+
m_dtd = xmlParseDTD(NULL, (const xmlChar *)m_resource.c_str());
50+
if (m_dtd == NULL) {
51+
std::string err = std::string("XML: Failed to load DTD: ") \
52+
+ m_resource;
53+
t->debug(4, err);
54+
return true;
55+
}
56+
5757
if (t->m_xml->m_data.doc == NULL) {
5858
t->debug(4, "XML document tree could not "\
5959
"be found for DTD validation.");

src/operators/validate_schema.cc

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ bool ValidateSchema::init(const std::string &file, const char **error) {
3333
return false;
3434
}
3535

36+
return true;
37+
}
38+
39+
40+
bool ValidateSchema::evaluate(Transaction *t,
41+
const std::string &str) {
42+
int rc;
43+
3644
m_parserCtx = xmlSchemaNewParserCtxt(m_resource.c_str());
3745
if (m_parserCtx == NULL) {
3846
std::stringstream err;
@@ -42,8 +50,8 @@ bool ValidateSchema::init(const std::string &file, const char **error) {
4250
if (m_err.empty() == false) {
4351
err << m_err;
4452
}
45-
*error = strdup(err.str().c_str());
46-
return false;
53+
t->debug(4, err.str());
54+
return true;
4755
}
4856

4957
xmlSchemaSetParserErrors(m_parserCtx,
@@ -65,9 +73,9 @@ bool ValidateSchema::init(const std::string &file, const char **error) {
6573
if (m_err.empty() == false) {
6674
err << " " << m_err;
6775
}
68-
*error = strdup(err.str().c_str());
76+
t->debug(4, err.str());
6977
xmlSchemaFreeParserCtxt(m_parserCtx);
70-
return false;
78+
return true;
7179
}
7280

7381
m_validCtx = xmlSchemaNewValidCtxt(m_schema);
@@ -76,18 +84,10 @@ bool ValidateSchema::init(const std::string &file, const char **error) {
7684
if (m_err.empty() == false) {
7785
err << " " << m_err;
7886
}
79-
*error = strdup(err.str().c_str());
80-
return false;
87+
t->debug(4, err.str());
88+
return true;
8189
}
8290

83-
return true;
84-
}
85-
86-
87-
bool ValidateSchema::evaluate(Transaction *t,
88-
const std::string &str) {
89-
int rc;
90-
9191
/* Send validator errors/warnings to msr_log */
9292
xmlSchemaSetValidErrors(m_validCtx,
9393
(xmlSchemaValidityErrorFunc)error_runtime,

src/parser/seclang-parser.yy

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ using modsecurity::Variables::XML;
213213
%token <std::string> CONFIG_DIR_DEBUG_LOG
214214
%token <std::string> CONFIG_DIR_DEBUG_LVL
215215

216+
%token <std::string> CONFIG_XML_EXTERNAL_ENTITY
217+
216218
%token <std::string> CONFIG_DIR_SEC_ACTION
217219
%token <std::string> CONFIG_DIR_SEC_DEFAULT_ACTION
218220
%token <std::string> CONFIG_DIR_SEC_MARKER
@@ -652,6 +654,14 @@ expression:
652654
driver.m_responseBodyTypeToBeInspected.insert(*it);
653655
}
654656
}
657+
| CONFIG_XML_EXTERNAL_ENTITY CONFIG_VALUE_OFF
658+
{
659+
driver.secXMLExternalEntity = false;
660+
}
661+
| CONFIG_XML_EXTERNAL_ENTITY CONFIG_VALUE_ON
662+
{
663+
driver.secXMLExternalEntity = true;
664+
}
655665
| CONGIG_DIR_SEC_TMP_DIR
656666
| CONGIG_DIR_SEC_DATA_DIR
657667
| CONGIG_DIR_SEC_ARG_SEP

src/parser/seclang-scanner.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ CONFIG_DIR_RULE_ENG (?i:SecRuleEngine)
8383
CONFIG_DIR_REQ_BODY (?i:SecRequestBodyAccess)
8484
CONFIG_DIR_RES_BODY (?i:SecResponseBodyAccess)
8585

86+
CONFIG_XML_EXTERNAL_ENTITY (?i:SecXmlExternalEntity)
8687

8788
CONFIG_DIR_AUDIT_DIR_MOD (?i:SecAuditLogDirMode)
8889
CONFIG_DIR_AUDIT_DIR (?i:SecAuditLogStorageDir)
@@ -285,6 +286,7 @@ CONFIG_DIR_UNICODE_MAP_FILE (?i:SecUnicodeMapFile)
285286
{CONFIG_COMPONENT_SIG}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); }
286287
287288
%{ /* Other configurations */ %}
289+
{CONFIG_XML_EXTERNAL_ENTITY} { return yy::seclang_parser::make_CONFIG_XML_EXTERNAL_ENTITY(yytext, *driver.loc.back()); }
288290
{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()); }
289291
{CONFIG_DIR_PCRE_MATCH_LIMIT}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_PCRE_MATCH_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }
290292
{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()); }

src/request_body_processor/xml.cc

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,25 @@ XML::~XML() {
4141

4242

4343
bool XML::init() {
44-
// xmlParserInputBufferCreateFilenameFunc entity;
45-
// entity = xmlParserInputBufferCreateFilenameDefault(
46-
// this->unloadExternalEntity);
44+
xmlParserInputBufferCreateFilenameFunc entity;
45+
if (m_transaction->m_rules->secXMLExternalEntity == true) {
46+
entity = xmlParserInputBufferCreateFilenameDefault(
47+
__xmlParserInputBufferCreateFilename);
48+
} else {
49+
entity = xmlParserInputBufferCreateFilenameDefault(
50+
this->unloadExternalEntity);
51+
}
52+
4753
return true;
4854
}
4955

5056

57+
xmlParserInputBufferPtr XML::unloadExternalEntity(const char *URI,
58+
xmlCharEncoding enc) {
59+
return NULL;
60+
}
61+
62+
5163
bool XML::processChunk(const char *buf, unsigned int size) {
5264
/* We want to initialise our parsing context here, to
5365
* enable us to pass it the first chunk of data so that

src/request_body_processor/xml.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <iostream>
2222

2323
#include "modsecurity/transaction.h"
24+
#include "modsecurity/rules.h"
2425

2526
#ifndef SRC_REQUEST_BODY_PROCESSOR_XML_H_
2627
#define SRC_REQUEST_BODY_PROCESSOR_XML_H_
@@ -48,7 +49,7 @@ class XML {
4849
bool processChunk(const char *buf, unsigned int size);
4950
bool complete();
5051
static xmlParserInputBufferPtr unloadExternalEntity(const char *URI,
51-
xmlCharEncoding enc) { return NULL; }
52+
xmlCharEncoding enc);
5253

5354
#ifndef NO_LOGS
5455
void debug(int a, std::string str) {

src/rules.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ int Rules::merge(Driver *from) {
206206
this->secRuleEngine = from->secRuleEngine;
207207
this->secRequestBodyAccess = from->secRequestBodyAccess;
208208
this->secResponseBodyAccess = from->secResponseBodyAccess;
209+
this->secXMLExternalEntity = from->secXMLExternalEntity;
209210
if (from->m_debugLog && this->m_debugLog &&
210211
from->m_debugLog->isLogFileSet()) {
211212
this->m_debugLog->setDebugLogFile(from->m_debugLog->getDebugLogFile());

src/variables/xml.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include <utility>
3535

3636
#include "modsecurity/transaction.h"
37+
#include "modsecurity/rules_properties.h"
38+
#include "modsecurity/rules.h"
3739

3840
#include "src/request_body_processor/xml.h"
3941
#include "src/actions/action.h"

0 commit comments

Comments
 (0)