Adds support to removeComments transformation on libmodsec

Issue #970
This commit is contained in:
Felipe Zimmerle 2016-05-25 11:17:32 -03:00
parent 08df949bf6
commit b7e82261ce
3 changed files with 80 additions and 15 deletions

View File

@ -30,25 +30,87 @@ namespace modsecurity {
namespace actions { namespace actions {
namespace transformations { namespace transformations {
RemoveComments::RemoveComments(std::string action)
: Transformation(action) {
this->action_kind = 1;
}
std::string RemoveComments::evaluate(std::string value, std::string RemoveComments::evaluate(std::string value,
Transaction *transaction) { Transaction *transaction) {
/** std::string ret;
* @todo Implement the transformation RemoveComments unsigned char *input = NULL;
*/
if (transaction) { input = reinterpret_cast<unsigned char *>
#ifndef NO_LOGS (malloc(sizeof(char) * value.length()+1));
transaction->debug(4, "Transformation RemoveComments is not " \
"implemented yet."); if (input == NULL) {
#endif return "";
} }
return value;
memcpy(input, value.c_str(), value.length()+1);
u_int64_t input_len = value.size();
u_int64_t i, j, incomment;
int changed = 0;
i = j = incomment = 0;
while (i < input_len) {
if (incomment == 0) {
if ((input[i] == '/') && (i + 1 < input_len)
&& (input[i + 1] == '*')) {
changed = 1;
incomment = 1;
i += 2;
} else if ((input[i] == '<') && (i + 1 < input_len)
&& (input[i + 1] == '!') && (i + 2 < input_len)
&& (input[i+2] == '-') && (i + 3 < input_len)
&& (input[i + 3] == '-') && (incomment == 0)) {
incomment = 1;
changed = 1;
i += 4;
} else if ((input[i] == '-') && (i + 1 < input_len)
&& (input[i + 1] == '-') && (incomment == 0)) {
changed = 1;
input[i] = ' ';
break;
} else if (input[i] == '#' && (incomment == 0)) {
changed = 1;
input[i] = ' ';
break;
} else {
input[j] = input[i];
i++;
j++;
}
} else {
if ((input[i] == '*') && (i + 1 < input_len)
&& (input[i + 1] == '/')) {
incomment = 0;
i += 2;
input[j] = input[i];
i++;
j++;
} else if ((input[i] == '-') && (i + 1 < input_len)
&& (input[i + 1] == '-') && (i + 2 < input_len)
&& (input[i+2] == '>')) {
incomment = 0;
i += 3;
input[j] = input[i];
i++;
j++;
} else {
i++;
}
}
}
if (incomment) {
input[j++] = ' ';
}
ret.assign(reinterpret_cast<char *>(input), j);
free(input);
return ret;
} }
} // namespace transformations } // namespace transformations
} // namespace actions } // namespace actions
} // namespace modsecurity } // namespace modsecurity

View File

@ -28,13 +28,16 @@ class Transaction;
namespace actions { namespace actions {
namespace transformations { namespace transformations {
class RemoveComments : public Transformation { class RemoveComments : public Transformation {
public: public:
explicit RemoveComments(std::string action); explicit RemoveComments(std::string action) : Transformation(action) { }
std::string evaluate(std::string exp, std::string evaluate(std::string exp,
Transaction *transaction) override; Transaction *transaction) override;
}; };
} // namespace transformations } // namespace transformations
} // namespace actions } // namespace actions
} // namespace modsecurity } // namespace modsecurity

View File

@ -98,7 +98,7 @@ Transformation* Transformation::instantiate(std::string a) {
IF_MATCH(parity_odd_7bit) { return new ParityOdd7bit(a); } IF_MATCH(parity_odd_7bit) { return new ParityOdd7bit(a); }
IF_MATCH(parity_zero_7bit) { return new ParityZero7bit(a); } IF_MATCH(parity_zero_7bit) { return new ParityZero7bit(a); }
IF_MATCH(removeCommentsChar) { return new RemoveCommentsChar(a); } IF_MATCH(removeCommentsChar) { return new RemoveCommentsChar(a); }
IF_MATCH(remove_comments) { return new RemoveComments(a); } IF_MATCH(removeComments) { return new RemoveComments(a); }
IF_MATCH(removeNulls) { return new RemoveNulls(a); } IF_MATCH(removeNulls) { return new RemoveNulls(a); }
IF_MATCH(removeWhitespace) { return new RemoveWhitespace(a); } IF_MATCH(removeWhitespace) { return new RemoveWhitespace(a); }
IF_MATCH(compressWhitespace) { return new CompressWhitespace(a); } IF_MATCH(compressWhitespace) { return new CompressWhitespace(a); }