Adds support to URL decode transformation

This commit is contained in:
Felipe Zimmerle
2015-10-22 17:20:31 -03:00
parent 0227fe9d6c
commit e3e8bac138
7 changed files with 113 additions and 25 deletions

View File

@@ -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); }

View File

@@ -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

View File

@@ -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