mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
Adds support to URL decode transformation
This commit is contained in:
parent
0227fe9d6c
commit
e3e8bac138
@ -106,7 +106,7 @@ Transformation* Transformation::instantiate(std::string a) {
|
||||
IF_MATCH(trimLeft) { return new TrimLeft(a); }
|
||||
IF_MATCH(trimRight) { return new TrimRight(a); }
|
||||
IF_MATCH(trim) { return new Trim(a); }
|
||||
IF_MATCH(url_decode) { return new UrlDecode(a); }
|
||||
IF_MATCH(urlDecode) { return new UrlDecode(a); }
|
||||
IF_MATCH(urlDecodeUni) { return new UrlDecodeUni(a); }
|
||||
IF_MATCH(url_encode) { return new UrlEncode(a); }
|
||||
IF_MATCH(utf8_to_unicode) { return new Utf8Unicode(a); }
|
||||
|
@ -24,12 +24,71 @@
|
||||
|
||||
#include "modsecurity/assay.h"
|
||||
#include "actions/transformations/transformation.h"
|
||||
|
||||
#include "src/utils.h"
|
||||
|
||||
namespace ModSecurity {
|
||||
namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
int UrlDecode::urldecode_nonstrict_inplace(unsigned char *input,
|
||||
long int input_len, int *invalid_count, int *changed) {
|
||||
unsigned char *d = (unsigned char *)input;
|
||||
long int i, count;
|
||||
|
||||
*changed = 0;
|
||||
|
||||
if (input == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = count = 0;
|
||||
while (i < input_len) {
|
||||
if (input[i] == '%') {
|
||||
/* Character is a percent sign. */
|
||||
|
||||
/* Are there enough bytes available? */
|
||||
if (i + 2 < input_len) {
|
||||
char c1 = input[i + 1];
|
||||
char c2 = input[i + 2];
|
||||
if (VALID_HEX(c1) && VALID_HEX(c2)) {
|
||||
unsigned long uni = x2c(&input[i + 1]);
|
||||
|
||||
*d++ = (wchar_t)uni;
|
||||
count++;
|
||||
i += 3;
|
||||
*changed = 1;
|
||||
} else {
|
||||
/* Not a valid encoding, skip this % */
|
||||
*d++ = input[i++];
|
||||
count ++;
|
||||
(*invalid_count)++;
|
||||
}
|
||||
} else {
|
||||
/* Not enough bytes available, copy the raw bytes. */
|
||||
*d++ = input[i++];
|
||||
count ++;
|
||||
(*invalid_count)++;
|
||||
}
|
||||
} else {
|
||||
/* Character is not a percent sign. */
|
||||
if (input[i] == '+') {
|
||||
*d++ = ' ';
|
||||
*changed = 1;
|
||||
} else {
|
||||
*d++ = input[i];
|
||||
}
|
||||
count++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
*d = '\0';
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
UrlDecode::UrlDecode(std::string action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
@ -37,17 +96,25 @@ UrlDecode::UrlDecode(std::string action)
|
||||
|
||||
std::string UrlDecode::evaluate(std::string value,
|
||||
Assay *assay) {
|
||||
/**
|
||||
* @todo Implement the transformation UrlDecode
|
||||
*/
|
||||
if (assay) {
|
||||
#ifndef NO_LOGS
|
||||
assay->debug(4, "Transformation UrlDecode is not implemented yet.");
|
||||
#endif
|
||||
}
|
||||
return value;
|
||||
unsigned char *val = NULL;
|
||||
int invalid_count;
|
||||
int changed;
|
||||
|
||||
val = (unsigned char *) malloc(sizeof(char) * value.size() + 1);
|
||||
memcpy(val, value.c_str(), value.size() + 1);
|
||||
val[value.size()] = '\0';
|
||||
|
||||
int size = urldecode_nonstrict_inplace(val, value.size(), &invalid_count, &changed);
|
||||
std::string out;
|
||||
|
||||
out.append((const char *)val, size);
|
||||
|
||||
free(val);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
} // namespace ModSecurity
|
||||
|
@ -33,6 +33,9 @@ class UrlDecode : public Transformation {
|
||||
explicit UrlDecode(std::string action);
|
||||
std::string evaluate(std::string exp,
|
||||
Assay *assay) override;
|
||||
|
||||
int urldecode_nonstrict_inplace(unsigned char *input, long int input_len,
|
||||
int *invalid_count, int *changed);
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -43,11 +43,6 @@
|
||||
|
||||
#include "modsecurity/modsecurity.h"
|
||||
|
||||
#define VALID_HEX(X) (((X >= '0') && (X <= '9')) || \
|
||||
((X >= 'a') && (X <= 'f')) || ((X >= 'A') && (X <= 'F')))
|
||||
#define ISODIGIT(X) ((X >= '0') && (X <= '7'))
|
||||
#define NBSP 160
|
||||
|
||||
namespace ModSecurity {
|
||||
|
||||
std::string phase_name(int x) {
|
||||
@ -827,7 +822,7 @@ length:
|
||||
/**
|
||||
* Converts a single hexadecimal digit into a decimal value.
|
||||
*/
|
||||
static unsigned char xsingle2c(unsigned char *what) {
|
||||
unsigned char xsingle2c(unsigned char *what) {
|
||||
register unsigned char digit;
|
||||
|
||||
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
|
||||
@ -836,7 +831,7 @@ static unsigned char xsingle2c(unsigned char *what) {
|
||||
}
|
||||
|
||||
|
||||
static unsigned char x2c(unsigned char *what) {
|
||||
unsigned char x2c(unsigned char *what) {
|
||||
register unsigned char digit;
|
||||
|
||||
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
|
||||
|
11
src/utils.h
11
src/utils.h
@ -22,6 +22,13 @@
|
||||
|
||||
#ifndef SRC_UTILS_H_
|
||||
|
||||
|
||||
#define VALID_HEX(X) (((X >= '0') && (X <= '9')) || \
|
||||
((X >= 'a') && (X <= 'f')) || ((X >= 'A') && (X <= 'F')))
|
||||
#define ISODIGIT(X) ((X >= '0') && (X <= '7'))
|
||||
#define NBSP 160
|
||||
|
||||
|
||||
namespace ModSecurity {
|
||||
std::vector<std::string> split(std::string str, char delimiter);
|
||||
double random_number(const double from, const double to);
|
||||
@ -35,9 +42,9 @@ namespace ModSecurity {
|
||||
std::string toupper(std::string str);
|
||||
double cpu_seconds(void);
|
||||
int js_decode_nonstrict_inplace(unsigned char *input, int64_t input_len);
|
||||
static unsigned char x2c(unsigned char *what);
|
||||
unsigned char x2c(unsigned char *what);
|
||||
int css_decode_inplace(unsigned char *input, int64_t input_len);
|
||||
static unsigned char xsingle2c(unsigned char *what);
|
||||
unsigned char xsingle2c(unsigned char *what);
|
||||
int html_entities_decode_inplace(unsigned char *input, int input_len);
|
||||
int normalize_path_inplace(unsigned char *input, int input_len,
|
||||
int win, int *changed);
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 1f6f5235485e4a68f9cd57d2ac1ad4a0d4a7a3c4
|
||||
Subproject commit 76c4bd6460a870b481eb4d36fcead7818b20d7d9
|
@ -93,6 +93,11 @@ UnitTest *UnitTest::from_yajl_node(yajl_val &node) {
|
||||
u->param = YAJL_GET_STRING(val);
|
||||
} else if (strcmp(key, "input") == 0) {
|
||||
u->input = YAJL_GET_STRING(val);
|
||||
/*
|
||||
* Converting \\u0000 to \0 due to the following gcc bug:
|
||||
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53690
|
||||
*
|
||||
*/
|
||||
replaceAll(&(u->input), "\\0", '\0');
|
||||
replaceAll(&(u->input), "\\xe4", '\xe4');
|
||||
replaceAll(&(u->input), "\\x03", '\x03');
|
||||
@ -100,7 +105,7 @@ UnitTest *UnitTest::from_yajl_node(yajl_val &node) {
|
||||
replaceAll(&(u->input), "\\xc9", '\xc9');
|
||||
replaceAll(&(u->input), "\\x3b", '\x3b');
|
||||
replaceAll(&(u->input), "\\xFF", '\xff');
|
||||
replaceAll(&(u->input), "\\u0000", '\u0000');
|
||||
replaceAll(&(u->input), "\\u0000", '\0');
|
||||
} else if (strcmp(key, "name") == 0) {
|
||||
u->name = YAJL_GET_STRING(val);
|
||||
} else if (strcmp(key, "type") == 0) {
|
||||
@ -108,9 +113,20 @@ UnitTest *UnitTest::from_yajl_node(yajl_val &node) {
|
||||
} else if (strcmp(key, "ret") == 0) {
|
||||
u->ret = YAJL_GET_INTEGER(val);
|
||||
} else if (strcmp(key, "output") == 0) {
|
||||
u->output = YAJL_GET_STRING(val);
|
||||
replaceAll(&(u->output), "\\u0000", '\u0000');
|
||||
replaceAll(&(u->output), "\\0", '\u0000');
|
||||
u->output = std::string(YAJL_GET_STRING(val));
|
||||
/*
|
||||
* Converting \\u0000 to \0 due to the following gcc bug:
|
||||
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53690
|
||||
*
|
||||
*/
|
||||
replaceAll(&(u->output), "\\u0000", '\0');
|
||||
replaceAll(&(u->output), "\\xe4", '\xe4');
|
||||
replaceAll(&(u->output), "\\x03", '\x03');
|
||||
replaceAll(&(u->output), "\\xbf", '\xbf');
|
||||
replaceAll(&(u->output), "\\xc9", '\xc9');
|
||||
replaceAll(&(u->output), "\\x3b", '\x3b');
|
||||
replaceAll(&(u->output), "\\xFF", '\xff');
|
||||
replaceAll(&(u->output), "\\0", '\0');
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user