Fix SecUnicodeMapFile support

Makes SecUnicodeMapFile read the file and adjust transformation to use the
right variable.
This commit is contained in:
Victor Hora
2018-10-30 18:11:01 -04:00
committed by Felipe Zimmerle
parent 84ece3edcb
commit e3b9f7c913
12 changed files with 5885 additions and 5807 deletions

View File

@@ -279,6 +279,7 @@ libmodsecurity_la_SOURCES = \
rule_script.cc \
unique_id.cc \
rules_exceptions.cc \
rules_properties.cc \
${BODY_PROCESSORS} \
${ACTIONS} \
${ENGINES} \

View File

@@ -28,7 +28,10 @@
#include "modsecurity/transaction.h"
#include "src/actions/transformations/transformation.h"
#include "src/utils/string.h"
#include "src/utils/system.h"
#include "modsecurity/rules.h"
#include "modsecurity/rules_properties.h"
namespace modsecurity {
namespace actions {
@@ -88,8 +91,8 @@ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len,
if (t
&& t->m_rules->m_unicodeMapTable.m_set == true
&& t->m_rules->m_unicodeMapTable.m_unicode_map_table != NULL
&& t->m_rules->unicode_codepage > 0) {
&& t->m_rules->m_unicodeMapTable.m_unicodeMapTable != NULL
&& t->m_rules->m_unicodeMapTable.m_unicodeCodePage > 0) {
for (j = 5; j >= 2; j--) {
if (isxdigit((input[i+j]))) {
if (input[i+j] >= 97) {
@@ -106,7 +109,7 @@ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len,
if (Code >= 0 && Code <= 65535) {
Rules *r = t->m_rules;
hmap = r->m_unicodeMapTable.m_unicode_map_table[Code];
hmap = r->m_unicodeMapTable.m_unicodeMapTable[Code];
}
}

View File

@@ -16,15 +16,16 @@
#include <string>
#include "modsecurity/actions/action.h"
#include "modsecurity/rules_properties.h"
#include "src/actions/transformations/transformation.h"
#ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_
#define SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_
#ifdef __cplusplus
namespace modsecurity {
class Transaction;
namespace actions {
namespace transformations {

File diff suppressed because it is too large Load Diff

View File

@@ -96,6 +96,7 @@ class Driver;
#include "src/actions/tag.h"
#include "src/actions/transformations/none.h"
#include "src/actions/transformations/transformation.h"
#include "src/actions/transformations/url_decode_uni.h"
#include "src/actions/ver.h"
#include "src/actions/xmlns.h"
@@ -379,10 +380,8 @@ using modsecurity::operators::Operator;
std::unique_ptr<Variable> c(b); \
a = std::move(c);
#define CODEPAGE_SEPARATORS " \t\n\r"
#line 386 "seclang-parser.hh" // lalr1.cc:380
#line 385 "seclang-parser.hh" // lalr1.cc:380
# include <cassert>
# include <cstdlib> // std::abort
@@ -466,7 +465,7 @@ using modsecurity::operators::Operator;
namespace yy {
#line 470 "seclang-parser.hh" // lalr1.cc:380
#line 469 "seclang-parser.hh" // lalr1.cc:380
@@ -2893,9 +2892,9 @@ namespace yy {
enum
{
yyeof_ = 0,
yylast_ = 3329, ///< Last index in yytable_.
yylast_ = 3295, ///< Last index in yytable_.
yynnts_ = 16, ///< Number of nonterminal symbols.
yyfinal_ = 337, ///< Termination state number.
yyfinal_ = 336, ///< Termination state number.
yyterror_ = 1,
yyerrcode_ = 256,
yyntokens_ = 340 ///< Number of tokens.
@@ -6167,7 +6166,7 @@ namespace yy {
} // yy
#line 6171 "seclang-parser.hh" // lalr1.cc:380
#line 6170 "seclang-parser.hh" // lalr1.cc:380

View File

@@ -62,6 +62,7 @@ class Driver;
#include "src/actions/tag.h"
#include "src/actions/transformations/none.h"
#include "src/actions/transformations/transformation.h"
#include "src/actions/transformations/url_decode_uni.h"
#include "src/actions/ver.h"
#include "src/actions/xmlns.h"
@@ -345,8 +346,6 @@ using modsecurity::operators::Operator;
std::unique_ptr<Variable> c(b); \
a = std::move(c);
#define CODEPAGE_SEPARATORS " \t\n\r"
}
// The parsing context.
%param { modsecurity::Parser::Driver& driver }
@@ -1709,61 +1708,44 @@ expression:
driver.error(@0, "SecStatusEngine is not yet supported.");
YYERROR;
*/
| CONFIG_DIR_UNICODE_CODE_PAGE
{
long val;
val = atol($1.c_str());
if (val <= 0) {
std::stringstream ss;
ss << "Invalid setting for SecUnicodeCodePage: " << $1 << " ";
driver.error(@0, ss.str());
YYERROR;
}
driver.m_unicodeMapTable.m_unicode_codepage = val;
}
| CONFIG_DIR_UNICODE_MAP_FILE
{
std::string error;
std::vector<std::string> param;
double num = 0;
std::string f;
std::string file;
std::string err;
char *buf = NULL, *p = NULL, *savedptr = NULL;
int found = 0;
int code = 0;
unsigned int codepage = 0;
int Map = 0;
char *ucode = NULL, *hmap = NULL;
int processing = 0;
std::vector<std::string> param = utils::string::ssplit($1, ' ');
param = utils::string::ssplit($1, ' ');
if (param.size() <= 1) {
std::stringstream ss;
ss << "Failed to process unicode map, missing parameter: " << $1 << " ";
ss << err;
ss << "Failed to process unicode map, missing ";
ss << "parameter: " << $1 << " ";
driver.error(@0, ss.str());
YYERROR;
}
int num = 0;
try {
num = std::stod(param.back());
} catch (...) {
std::stringstream ss;
ss << "Failed to process unicode map, last parameter is expected to be a number: " << param.back() << " ";
ss << err;
ss << "Failed to process unicode map, last parameter is ";
ss << "expected to be a number: " << param.back() << " ";
driver.error(@0, ss.str());
YYERROR;
}
param.pop_back();
std::string f;
while (param.size() > 0) {
f = param.back() + " " + f;
if (f.empty()) {
f = param.back();
} else {
f = param.back() + " " + f;
}
param.pop_back();
}
std::string file = modsecurity::utils::find_resource(f,
driver.ref.back(), &err);
file = modsecurity::utils::find_resource(f, driver.ref.back(), &err);
if (file.empty()) {
std::stringstream ss;
ss << "Failed to locate the unicode map file from: " << f << " ";
@@ -1772,66 +1754,13 @@ expression:
YYERROR;
}
driver.m_unicodeMapTable.m_set = true;
driver.m_unicodeMapTable.m_unicode_map_table = static_cast<int *>(malloc(sizeof(int) * 65536));
ConfigUnicodeMap::loadConfig(file, num, &driver, &error);
// FIXME: that deservers to have its own file. Too much code to be here.
if (driver.m_unicodeMapTable.m_unicode_map_table == NULL) {
std::stringstream ss;
ss << "Failed to allocate memory for the unicode map file - " << $1 << " ";
ss << err;
driver.error(@0, ss.str());
if (!error.empty()) {
driver.error(@0, error);
YYERROR;
}
memset(driver.m_unicodeMapTable.m_unicode_map_table, -1, (sizeof(int)*65536));
/* Setting some unicode values - http://tools.ietf.org/html/rfc3490#section-3.1 */
/* Set 0x3002 -> 0x2e */
driver.m_unicodeMapTable.m_unicode_map_table[0x3002] = 0x2e;
/* Set 0xFF61 -> 0x2e */
driver.m_unicodeMapTable.m_unicode_map_table[0xff61] = 0x2e;
/* Set 0xFF0E -> 0x2e */
driver.m_unicodeMapTable.m_unicode_map_table[0xff0e] = 0x2e;
/* Set 0x002E -> 0x2e */
driver.m_unicodeMapTable.m_unicode_map_table[0x002e] = 0x2e;
p = strtok_r(buf, CODEPAGE_SEPARATORS, &savedptr);
while (p != NULL) {
codepage = atol(p);
if (codepage == driver.m_unicodeMapTable.m_unicode_codepage) {
found = 1;
}
if (found == 1 && (strchr(p,':') != NULL)) {
char *mapping = strdup(p);
processing = 1;
if (mapping != NULL) {
ucode = strtok_r(mapping, ":", &hmap);
sscanf(ucode, "%x", &code);
sscanf(hmap, "%x", &Map);
if (code >= 0 && code <= 65535) {
driver.m_unicodeMapTable.m_unicode_map_table[code] = Map;
}
free(mapping);
mapping = NULL;
}
}
if (processing == 1 && (strchr(p,':') == NULL)) {
free(buf);
buf = NULL;
break;
}
p = strtok_r(NULL,CODEPAGE_SEPARATORS,&savedptr);
}
}
| CONFIG_SEC_COLLECTION_TIMEOUT
{

File diff suppressed because it is too large Load Diff

View File

@@ -372,7 +372,6 @@ CONFIG_DIR_SEC_DEFAULT_ACTION (?i:SecDefaultAction)
CONFIG_SEC_DISABLE_BACKEND_COMPRESS (?i:SecDisableBackendCompression)
CONFIG_DIR_SEC_MARKER (?i:SecMarker)
CONFIG_DIR_UNICODE_MAP_FILE (?i:SecUnicodeMapFile)
CONFIG_DIR_UNICODE_CODE_PAGE (?i:SecUnicodeCodePage)
CONFIG_INCLUDE (?i:Include)
CONFIG_SEC_COLLECTION_TIMEOUT (?i:SecCollectionTimeout)
CONFIG_SEC_HTTP_BLKEY (?i:SecHttpBlKey)
@@ -775,7 +774,6 @@ EQUALS_MINUS (?i:=\-)
{CONFIG_DIR_SEC_MARKER}[ \t]+["]{NEW_LINE_FREE_TEXT}["] { return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_SEC_MARKER}[ \t]+{NEW_LINE_FREE_TEXT} { return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_UNICODE_MAP_FILE}[ ]+{FREE_TEXT_NEW_LINE}[ ]+{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_UNICODE_MAP_FILE(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_UNICODE_CODE_PAGE}[ ]{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_DIR_UNICODE_CODE_PAGE(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_SEC_REMOVE_RULES_BY_ID}[ ]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_RULE_REMOVE_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }
{CONFIG_SEC_REMOVE_RULES_BY_MSG}[ \t]+{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }
{CONFIG_SEC_REMOVE_RULES_BY_MSG}[ \t]+["]{FREE_TEXT_NEW_LINE}["] { return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }

133
src/rules_properties.cc Normal file
View File

@@ -0,0 +1,133 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org.
*
*/
#include "modsecurity/rules_properties.h"
#include <string>
#include "src/utils/string.h"
#include "src/variables/variable.h"
namespace modsecurity {
void ConfigUnicodeMap::loadConfig(std::string f, double configCodePage,
RulesProperties *driver, std::string *errg) {
char *buf = NULL;
char *hmap = NULL;
char *p = NULL;
char *savedptr = NULL;
char *ucode = NULL;
int code = 0;
int found = 0;
int length = 0;
int Map = 0;
int processing = 0;
unsigned int codepage = 0;
driver->m_unicodeMapTable.m_set = true;
driver->m_unicodeMapTable.m_unicodeCodePage = configCodePage;
std::unique_ptr<int[]> a(new int[65536], std::default_delete<int[]>());
driver->m_unicodeMapTable.m_unicodeMapTable = std::move(a);
memset(driver->m_unicodeMapTable.m_unicodeMapTable.get(), -1,
(sizeof(int)*65536));
/* Setting some unicode values - http://tools.ietf.org/html/rfc3490#section-3.1 */
/* Set 0x3002 -> 0x2e */
driver->m_unicodeMapTable.m_unicodeMapTable[0x3002] = 0x2e;
/* Set 0xFF61 -> 0x2e */
driver->m_unicodeMapTable.m_unicodeMapTable[0xff61] = 0x2e;
/* Set 0xFF0E -> 0x2e */
driver->m_unicodeMapTable.m_unicodeMapTable[0xff0e] = 0x2e;
/* Set 0x002E -> 0x2e */
driver->m_unicodeMapTable.m_unicodeMapTable[0x002e] = 0x2e;
std::ifstream file_stream(f, std::ios::in | std::ios::binary);
if (file_stream) {
file_stream.seekg (0, file_stream.end);
length = file_stream.tellg();
file_stream.seekg (0, file_stream.beg);
} else {
std::stringstream ss;
ss << "Failed to open the unicode map file from: " << f << " ";
errg->assign(ss.str());
return;
}
if (length <= 0) {
std::stringstream ss;
ss << "Failed to open the unicode map file from: " << f << " ";
errg->assign(ss.str());
return;
}
buf = new char[length+1];
if (!buf) {
std::stringstream ss;
ss << "Failed to open the unicode map file from: " << f << " ";
errg->assign(ss.str());
return;
}
memset(buf, '\0', (sizeof(char)*(length+1)));
file_stream.read(buf, length);
file_stream.close();
p = strtok_r(buf, CODEPAGE_SEPARATORS, &savedptr);
while (p != NULL) {
codepage = atol(p);
if (codepage == configCodePage) {
found = 1;
}
if (found == 1 && (strchr(p,':') != NULL)) {
char *mapping = strdup(p);
processing = 1;
if (mapping != NULL) {
ucode = strtok_r(mapping, ":", &hmap);
sscanf(ucode, "%x", &code);
sscanf(hmap, "%x", &Map);
if (code >= 0 && code <= 65535) {
driver->m_unicodeMapTable.m_unicodeMapTable[code] = Map;
}
free(mapping);
mapping = NULL;
}
}
if (processing == 1 && (strchr(p,':') == NULL)) {
break;
}
if (!savedptr) {
break;
}
p = strtok_r(NULL, CODEPAGE_SEPARATORS, &savedptr);
}
delete[] buf;
}
} // namespace modsecurity