mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 13:56:01 +03:00
Refactoring: Makes transformations to work with new execute signature
This commit is contained in:
parent
ef9a63e610
commit
5cb58b412c
@ -39,6 +39,7 @@ namespace actions {
|
||||
|
||||
class Action {
|
||||
public:
|
||||
|
||||
explicit Action(const std::string& _action)
|
||||
: m_isNone(false),
|
||||
temporaryAction(false),
|
||||
@ -81,6 +82,17 @@ class Action {
|
||||
RuleMessage &ruleMessage) {
|
||||
return execute(rule, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is meant to be used by transformations — a particular
|
||||
* type of action.
|
||||
*
|
||||
*/
|
||||
virtual void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
};
|
||||
|
||||
virtual bool init(std::string *error) { return true; }
|
||||
virtual bool isDisruptive() { return false; }
|
||||
|
||||
|
@ -26,14 +26,15 @@
|
||||
|
||||
#include "modsecurity/transaction.h"
|
||||
#include "modsecurity/rule.h"
|
||||
#include "modsecurity/rule_with_operator.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace modsecurity {
|
||||
|
||||
|
||||
namespace actions {
|
||||
class Tag;
|
||||
};
|
||||
class RuleWithActions;
|
||||
|
||||
class RuleMessage {
|
||||
public:
|
||||
@ -112,108 +113,22 @@ class RuleMessage {
|
||||
static std::string _details(const RuleMessage *rm);
|
||||
static std::string _errorLogTail(const RuleMessage *rm);
|
||||
|
||||
RuleWithActions *getRule() const {
|
||||
return m_rule;
|
||||
}
|
||||
|
||||
void setRule(RuleWithActions *rule) {
|
||||
m_rule = rule;
|
||||
}
|
||||
|
||||
bool isSettle() const {
|
||||
return m_rule != nullptr;
|
||||
}
|
||||
|
||||
int getRuleId() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getId();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getPhase() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getPhase();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string getFileName() const {
|
||||
if (m_rule) {
|
||||
return *m_rule->getFileName().get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
int getLineNumber() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getLineNumber();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string getRev() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getRevision();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string getVer() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getVersion();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
int getMaturity() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getMaturity();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getAccuracy() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getAccuracy();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string getClientIpAddress() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_clientIpAddress.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string getServerIpAddress() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_serverIpAddress.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string getRequestId() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_id.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string getUri() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_uri_no_query_string_decoded.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool isDisruptive() const {
|
||||
if (m_rule) {
|
||||
return m_rule->hasDisruptiveAction();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
RuleWithActions *getRule() const;
|
||||
void setRule(RuleWithActions *rule);
|
||||
bool isSettle() const;
|
||||
int getRuleId() const;
|
||||
int getPhase() const;
|
||||
std::string getFileName() const;
|
||||
int getLineNumber() const;
|
||||
std::string getRev() const;
|
||||
std::string getVer() const;
|
||||
int getMaturity() const;
|
||||
int getAccuracy() const;
|
||||
std::string getClientIpAddress() const;
|
||||
std::string getServerIpAddress() const;
|
||||
std::string getRequestId() const;
|
||||
std::string getUri() const;
|
||||
bool isDisruptive() const;
|
||||
|
||||
int m_severity;
|
||||
std::list<std::string> m_tags;
|
||||
|
@ -49,9 +49,6 @@ class Transformation;
|
||||
}
|
||||
}
|
||||
|
||||
using TransformationResult = std::pair<std::shared_ptr<std::string>,
|
||||
std::shared_ptr<std::string>>;
|
||||
using TransformationResults = std::list<TransformationResult>;
|
||||
using Transformation = actions::transformations::Transformation;
|
||||
using Transformations = std::vector<std::shared_ptr<Transformation> >;
|
||||
using TransformationsPtr = std::vector<Transformation *>;
|
||||
@ -67,6 +64,43 @@ using MatchActionsPtr = std::vector<actions::Action *>;
|
||||
using XmlNSs = std::vector<std::shared_ptr<actions::XmlNS> >;
|
||||
using XmlNSsPtr = std::vector<actions::XmlNS *>;
|
||||
|
||||
using ModSecStackString = std::basic_string<char, std::char_traits<char>, std::allocator<char> >;
|
||||
|
||||
class TransformationResult {
|
||||
public:
|
||||
TransformationResult(
|
||||
ModSecStackString *after,
|
||||
std::string *transformation)
|
||||
: m_after(*after),
|
||||
m_transformation(transformation) { };
|
||||
|
||||
explicit TransformationResult(
|
||||
ModSecStackString *after)
|
||||
: m_after(*after),
|
||||
m_transformation(nullptr) { };
|
||||
|
||||
TransformationResult(const TransformationResult &t2)
|
||||
: m_after(t2.m_after),
|
||||
m_transformation(t2.m_transformation) { };
|
||||
|
||||
|
||||
ModSecStackString *getAfter() {
|
||||
return &m_after;
|
||||
}
|
||||
|
||||
|
||||
std::string *getTransformationName() {
|
||||
return m_transformation;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
ModSecStackString m_after;
|
||||
std::string *m_transformation;
|
||||
};
|
||||
|
||||
using TransformationsResults = std::list<TransformationResult>;
|
||||
|
||||
|
||||
class RuleWithActions : public Rule {
|
||||
public:
|
||||
@ -183,18 +217,21 @@ class RuleWithActions : public Rule {
|
||||
bool context);
|
||||
|
||||
|
||||
static void executeTransformation(
|
||||
Transaction *transaction,
|
||||
TransformationsResults *ret,
|
||||
Transformation *transformation);
|
||||
|
||||
static void executeTransformation(
|
||||
Transaction *transaction,
|
||||
ModSecStackString in,
|
||||
TransformationsResults *ret,
|
||||
Transformation *transformation);
|
||||
|
||||
void executeTransformations(
|
||||
Transaction *transaction,
|
||||
const std::string &value,
|
||||
TransformationResults &ret);
|
||||
|
||||
inline void executeTransformation(
|
||||
actions::transformations::Transformation *a,
|
||||
std::shared_ptr<std::string> *value,
|
||||
Transaction *trans,
|
||||
TransformationResults *ret,
|
||||
std::string *path) const;
|
||||
|
||||
TransformationsResults &results);
|
||||
|
||||
void addAction(actions::Action *a);
|
||||
void addTransformation(std::shared_ptr<actions::transformations::Transformation> t) {
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
namespace modsecurity {
|
||||
|
||||
using TransformationsResults = std::list<TransformationResult>;
|
||||
|
||||
class RuleWithOperator : public RuleWithActions {
|
||||
public:
|
||||
|
@ -32,11 +32,12 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string Base64Decode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
void Base64Decode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
std::string value(in.c_str(), in.size());
|
||||
std::string ret = Utils::Base64::decode(value);
|
||||
|
||||
return ret;
|
||||
out.assign(ret.c_str(), ret.size());
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class Base64Decode : public Transformation {
|
||||
public:
|
||||
explicit Base64Decode(const std::string &action) : Transformation(action) { }
|
||||
explicit Base64Decode(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -32,11 +32,11 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string Base64DecodeExt::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret = Utils::Base64::decode_forgiven(value);
|
||||
|
||||
return ret;
|
||||
void Base64DecodeExt::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
std::string ret = Utils::Base64::decode_forgiven(in.c_str());
|
||||
out.assign(ret.c_str(), ret.size());
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class Base64DecodeExt : public Transformation {
|
||||
public:
|
||||
explicit Base64DecodeExt(const std::string &action) : Transformation(action) { }
|
||||
explicit Base64DecodeExt(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -32,11 +32,12 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string Base64Encode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret = Utils::Base64::encode(value);
|
||||
|
||||
return ret;
|
||||
void Base64Encode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
std::string ret = Utils::Base64::encode(
|
||||
std::string(in.c_str(), in.size()));
|
||||
out.assign(ret.c_str(), ret.size());
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class Base64Encode : public Transformation {
|
||||
public:
|
||||
explicit Base64Encode(const std::string &action) : Transformation(action) { }
|
||||
explicit Base64Encode(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -31,12 +31,12 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string CmdLine::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret;
|
||||
void CmdLine::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
int space = 0;
|
||||
|
||||
for (auto& a : value) {
|
||||
for (auto& a : in) {
|
||||
switch (a) {
|
||||
/* remove some characters */
|
||||
case '"':
|
||||
@ -53,7 +53,7 @@ std::string CmdLine::execute(const std::string &value,
|
||||
case '\r':
|
||||
case '\n':
|
||||
if (space == 0) {
|
||||
ret.append(" ");
|
||||
out.append(" ");
|
||||
space++;
|
||||
}
|
||||
break;
|
||||
@ -62,22 +62,20 @@ std::string CmdLine::execute(const std::string &value,
|
||||
case '/':
|
||||
case '(':
|
||||
if (space) {
|
||||
ret.pop_back();
|
||||
out.pop_back();
|
||||
}
|
||||
space = 0;
|
||||
ret.append(&a, 1);
|
||||
out.append(&a, 1);
|
||||
break;
|
||||
|
||||
/* copy normal characters */
|
||||
default :
|
||||
char b = std::tolower(a);
|
||||
ret.append(&b, 1);
|
||||
out.append(&b, 1);
|
||||
space = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,11 +30,12 @@ namespace transformations {
|
||||
|
||||
class CmdLine : public Transformation {
|
||||
public:
|
||||
explicit CmdLine(const std::string &action)
|
||||
explicit CmdLine(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -30,37 +30,32 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
CompressWhitespace::CompressWhitespace(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
std::string CompressWhitespace::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
|
||||
std::string a;
|
||||
void CompressWhitespace::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
int inWhiteSpace = 0;
|
||||
int i = 0;
|
||||
size_t i = 0;
|
||||
out.reserve(in.size());
|
||||
|
||||
while (i < value.size()) {
|
||||
if (isspace(value[i])) {
|
||||
while (i < in.size()) {
|
||||
if (isspace(in[i])) {
|
||||
if (inWhiteSpace) {
|
||||
i++;
|
||||
continue;
|
||||
} else {
|
||||
inWhiteSpace = 1;
|
||||
a.append(" ", 1);
|
||||
out.append(" ", 1);
|
||||
}
|
||||
} else {
|
||||
inWhiteSpace = 0;
|
||||
a.append(&value.at(i), 1);
|
||||
out.append(&in.at(i), 1);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class CompressWhitespace : public Transformation {
|
||||
public:
|
||||
explicit CompressWhitespace(const std::string &action) ;
|
||||
explicit CompressWhitespace(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -34,20 +34,19 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string CssDecode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
|
||||
void CssDecode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
char *tmp = reinterpret_cast<char *>(
|
||||
malloc(sizeof(char) * value.size() + 1));
|
||||
memcpy(tmp, value.c_str(), value.size() + 1);
|
||||
tmp[value.size()] = '\0';
|
||||
malloc(sizeof(char) * in.size() + 1));
|
||||
memcpy(tmp, in.c_str(), in.size() + 1);
|
||||
tmp[in.size()] = '\0';
|
||||
|
||||
CssDecode::css_decode_inplace(reinterpret_cast<unsigned char *>(tmp),
|
||||
value.size());
|
||||
in.size());
|
||||
|
||||
std::string ret(tmp, 0, value.size());
|
||||
out.assign(tmp, 0, in.size());
|
||||
free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,10 +31,12 @@ namespace transformations {
|
||||
|
||||
class CssDecode : public Transformation {
|
||||
public:
|
||||
explicit CssDecode(const std::string &action)
|
||||
explicit CssDecode(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
static int css_decode_inplace(unsigned char *input, int64_t input_len);
|
||||
};
|
||||
|
@ -31,11 +31,6 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
EscapeSeqDecode::EscapeSeqDecode(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
|
||||
int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input,
|
||||
int input_len) {
|
||||
@ -140,21 +135,17 @@ int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input,
|
||||
}
|
||||
|
||||
|
||||
std::string EscapeSeqDecode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
|
||||
void EscapeSeqDecode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
unsigned char *tmp = (unsigned char *) malloc(sizeof(char)
|
||||
* value.size() + 1);
|
||||
memcpy(tmp, value.c_str(), value.size() + 1);
|
||||
tmp[value.size()] = '\0';
|
||||
* in.size() + 1);
|
||||
memcpy(tmp, in.c_str(), in.size() + 1);
|
||||
tmp[in.size()] = '\0';
|
||||
|
||||
int size = ansi_c_sequences_decode_inplace(tmp, value.size());
|
||||
|
||||
std::string ret("");
|
||||
ret.assign(reinterpret_cast<char *>(tmp), size);
|
||||
int size = ansi_c_sequences_decode_inplace(tmp, in.size());
|
||||
out.assign(reinterpret_cast<char *>(tmp), size);
|
||||
free(tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -30,9 +30,13 @@ namespace transformations {
|
||||
|
||||
class EscapeSeqDecode : public Transformation {
|
||||
public:
|
||||
explicit EscapeSeqDecode(const std::string &action) ;
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
explicit EscapeSeqDecode(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
static int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len);
|
||||
};
|
||||
|
||||
|
@ -32,27 +32,25 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string HexDecode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret;
|
||||
void HexDecode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
unsigned char *input;
|
||||
int size = 0;
|
||||
|
||||
input = reinterpret_cast<unsigned char *>
|
||||
(malloc(sizeof(char) * value.length()+1));
|
||||
(malloc(sizeof(char) * in.length()+1));
|
||||
|
||||
if (input == NULL) {
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(input, value.c_str(), value.length()+1);
|
||||
memcpy(input, in.c_str(), in.length()+1);
|
||||
|
||||
size = inplace(input, value.length());
|
||||
size = inplace(input, in.length());
|
||||
|
||||
ret.assign(reinterpret_cast<char *>(input), size);
|
||||
out.assign(reinterpret_cast<char *>(input), size);
|
||||
free(input);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class HexDecode : public Transformation {
|
||||
public:
|
||||
explicit HexDecode(const std::string &action) : Transformation(action) { }
|
||||
explicit HexDecode(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
static int inplace(unsigned char *data, int len);
|
||||
};
|
||||
|
@ -31,23 +31,20 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
HexEncode::HexEncode(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
std::string HexEncode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
|
||||
void HexEncode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
std::stringstream result;
|
||||
for (std::size_t i=0; i < value.length(); i++) {
|
||||
unsigned int ii = (unsigned char)(value[i]);
|
||||
for (std::size_t i=0; i < in.length(); i++) {
|
||||
int ii = reinterpret_cast<char>(in[i]);
|
||||
result << std::setw(2) << std::setfill('0') << std::hex << ii;
|
||||
}
|
||||
|
||||
return result.str();
|
||||
out.assign(result.str().c_str());
|
||||
}
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
||||
|
@ -30,10 +30,13 @@ namespace transformations {
|
||||
|
||||
class HexEncode : public Transformation {
|
||||
public:
|
||||
explicit HexEncode(const std::string &action);
|
||||
explicit HexEncode(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -33,26 +33,24 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string HtmlEntityDecode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret;
|
||||
void HtmlEntityDecode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
unsigned char *input;
|
||||
|
||||
input = reinterpret_cast<unsigned char *>
|
||||
(malloc(sizeof(char) * value.length()+1));
|
||||
(malloc(sizeof(char) * in.length()+1));
|
||||
|
||||
if (input == NULL) {
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(input, value.c_str(), value.length()+1);
|
||||
memcpy(input, in.c_str(), in.length()+1);
|
||||
|
||||
size_t i = inplace(input, value.length());
|
||||
size_t i = inplace(input, in.length());
|
||||
|
||||
ret.assign(reinterpret_cast<char *>(input), i);
|
||||
out.assign(reinterpret_cast<char *>(input), i);
|
||||
free(input);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,8 +36,9 @@ class HtmlEntityDecode : public Transformation {
|
||||
explicit HtmlEntityDecode(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
static int inplace(unsigned char *input, uint64_t input_len);
|
||||
};
|
||||
|
@ -34,26 +34,24 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string JsDecode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret;
|
||||
void JsDecode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
unsigned char *input;
|
||||
|
||||
input = reinterpret_cast<unsigned char *>
|
||||
(malloc(sizeof(char) * value.length()+1));
|
||||
(malloc(sizeof(char) * in.length()+1));
|
||||
|
||||
if (input == NULL) {
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(input, value.c_str(), value.length()+1);
|
||||
memcpy(input, in.c_str(), in.length()+1);
|
||||
|
||||
size_t i = inplace(input, value.length());
|
||||
size_t i = inplace(input, in.length());
|
||||
|
||||
ret.assign(reinterpret_cast<char *>(input), i);
|
||||
out.assign(reinterpret_cast<char *>(input), i);
|
||||
free(input);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,8 +33,10 @@ class JsDecode : public Transformation {
|
||||
explicit JsDecode(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
static int inplace(unsigned char *input, uint64_t input_len);
|
||||
};
|
||||
|
||||
|
@ -30,15 +30,11 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
Length::Length(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
std::string Length::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
|
||||
return std::to_string(value.size());
|
||||
void Length::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
out.assign(std::to_string(in.size()).c_str());
|
||||
}
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class Length : public Transformation {
|
||||
public:
|
||||
explicit Length(const std::string &action);
|
||||
explicit Length(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -27,22 +27,17 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
LowerCase::LowerCase(const std::string &a)
|
||||
: Transformation(a) {
|
||||
}
|
||||
|
||||
std::string LowerCase::execute(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
void LowerCase::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
std::locale loc;
|
||||
std::string value(val);
|
||||
|
||||
for (std::string::size_type i=0; i < value.length(); ++i) {
|
||||
value[i] = std::tolower(value[i], loc);
|
||||
out.resize(in.size());
|
||||
for (std::string::size_type i=0; i < in.size(); ++i) {
|
||||
out[i] = std::tolower(in[i], loc);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
||||
|
@ -32,9 +32,12 @@ namespace transformations {
|
||||
|
||||
class LowerCase : public Transformation {
|
||||
public:
|
||||
explicit LowerCase(const std::string &action);
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
explicit LowerCase(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -31,11 +31,12 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string Md5::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret = Utils::Md5::digest(value);
|
||||
void Md5::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
std::string ret = Utils::Md5::digest(std::string(in.c_str(), in.size()));
|
||||
|
||||
return ret;
|
||||
out.assign(ret.c_str(), ret.size());
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class Md5 : public Transformation {
|
||||
public:
|
||||
explicit Md5(const std::string &action) : Transformation(action) { }
|
||||
explicit Md5(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -31,10 +31,9 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string None::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
return value;
|
||||
}
|
||||
void None::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) { }
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -34,8 +34,9 @@ class None : public Transformation {
|
||||
: Transformation(action)
|
||||
{ m_isNone = true; }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -32,28 +32,23 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
NormalisePath::NormalisePath(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
std::string NormalisePath::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
void NormalisePath::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
int changed = 0;
|
||||
|
||||
char *tmp = reinterpret_cast<char *>(
|
||||
malloc(sizeof(char) * value.size() + 1));
|
||||
memcpy(tmp, value.c_str(), value.size() + 1);
|
||||
tmp[value.size()] = '\0';
|
||||
malloc(sizeof(char) * in.size() + 1));
|
||||
memcpy(tmp, in.c_str(), in.size() + 1);
|
||||
tmp[in.size()] = '\0';
|
||||
|
||||
int i = normalize_path_inplace((unsigned char *)tmp,
|
||||
value.size(), 0, &changed);
|
||||
in.size(), 0, &changed);
|
||||
|
||||
std::string ret("");
|
||||
ret.assign(tmp, i);
|
||||
out.assign(tmp, i);
|
||||
free(tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class NormalisePath : public Transformation {
|
||||
public:
|
||||
explicit NormalisePath(const std::string &action);
|
||||
explicit NormalisePath(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
static int normalize_path_inplace(unsigned char *input, int input_len,
|
||||
int win, int *changed);
|
||||
|
@ -34,24 +34,23 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string NormalisePathWin::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
void NormalisePathWin::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
int changed;
|
||||
|
||||
char *tmp = reinterpret_cast<char *>(
|
||||
malloc(sizeof(char) * value.size() + 1));
|
||||
memcpy(tmp, value.c_str(), value.size() + 1);
|
||||
tmp[value.size()] = '\0';
|
||||
malloc(sizeof(char) * in.size() + 1));
|
||||
memcpy(tmp, in.c_str(), in.size() + 1);
|
||||
tmp[in.size()] = '\0';
|
||||
|
||||
int i = NormalisePath::normalize_path_inplace(
|
||||
reinterpret_cast<unsigned char *>(tmp),
|
||||
value.size(), 1, &changed);
|
||||
in.size(), 1, &changed);
|
||||
|
||||
std::string ret("");
|
||||
ret.assign(tmp, i);
|
||||
out.assign(tmp, i);
|
||||
free(tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,8 +33,9 @@ class NormalisePathWin : public Transformation {
|
||||
explicit NormalisePathWin(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -32,28 +32,27 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string ParityEven7bit::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret;
|
||||
void ParityEven7bit::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
unsigned char *input;
|
||||
|
||||
input = reinterpret_cast<unsigned char *>
|
||||
(malloc(sizeof(char) * value.length()+1));
|
||||
(malloc(sizeof(char) * in.length()+1));
|
||||
|
||||
if (input == NULL) {
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
std::memcpy(input, value.c_str(), value.length()+1);
|
||||
std::memcpy(input, in.c_str(), in.length()+1);
|
||||
|
||||
inplace(input, value.length());
|
||||
inplace(input, in.length());
|
||||
|
||||
ret.assign(reinterpret_cast<char *>(input), value.length());
|
||||
out.assign(reinterpret_cast<char *>(input), in.length());
|
||||
free(input);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool ParityEven7bit::inplace(unsigned char *input, uint64_t input_len) {
|
||||
uint64_t i;
|
||||
|
||||
@ -76,7 +75,6 @@ bool ParityEven7bit::inplace(unsigned char *input, uint64_t input_len) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
||||
|
@ -30,9 +30,13 @@ namespace transformations {
|
||||
|
||||
class ParityEven7bit : public Transformation {
|
||||
public:
|
||||
explicit ParityEven7bit(const std::string &action) : Transformation(action) { }
|
||||
explicit ParityEven7bit(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
std::string execute(const std::string &exp, Transaction *transaction) override;
|
||||
static bool inplace(unsigned char *input, uint64_t input_len);
|
||||
};
|
||||
|
||||
|
@ -32,28 +32,27 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string ParityOdd7bit::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret;
|
||||
void ParityOdd7bit::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
unsigned char *input;
|
||||
|
||||
input = reinterpret_cast<unsigned char *>
|
||||
(malloc(sizeof(char) * value.length()+1));
|
||||
(malloc(sizeof(char) * in.length()+1));
|
||||
|
||||
if (input == NULL) {
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(input, value.c_str(), value.length()+1);
|
||||
memcpy(input, in.c_str(), in.length()+1);
|
||||
|
||||
inplace(input, value.length());
|
||||
inplace(input, in.length());
|
||||
|
||||
ret.assign(reinterpret_cast<char *>(input), value.length());
|
||||
out.assign(reinterpret_cast<char *>(input), in.length());
|
||||
free(input);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool ParityOdd7bit::inplace(unsigned char *input, uint64_t input_len) {
|
||||
uint64_t i;
|
||||
|
||||
|
@ -30,9 +30,13 @@ namespace transformations {
|
||||
|
||||
class ParityOdd7bit : public Transformation {
|
||||
public:
|
||||
explicit ParityOdd7bit(const std::string &action) : Transformation(action) { }
|
||||
explicit ParityOdd7bit(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
std::string execute(const std::string &exp, Transaction *transaction) override;
|
||||
static bool inplace(unsigned char *input, uint64_t input_len);
|
||||
};
|
||||
|
||||
|
@ -32,26 +32,24 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string ParityZero7bit::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret;
|
||||
void ParityZero7bit::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
unsigned char *input;
|
||||
|
||||
input = reinterpret_cast<unsigned char *>
|
||||
(malloc(sizeof(char) * value.length()+1));
|
||||
(malloc(sizeof(char) * in.length()+1));
|
||||
|
||||
if (input == NULL) {
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(input, value.c_str(), value.length()+1);
|
||||
memcpy(input, in.c_str(), in.length()+1);
|
||||
|
||||
inplace(input, value.length());
|
||||
inplace(input, in.length());
|
||||
|
||||
ret.assign(reinterpret_cast<char *>(input), value.length());
|
||||
out.assign(reinterpret_cast<char *>(input), in.length());
|
||||
free(input);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,9 +30,13 @@ namespace transformations {
|
||||
|
||||
class ParityZero7bit : public Transformation {
|
||||
public:
|
||||
explicit ParityZero7bit(const std::string &action) : Transformation(action) { }
|
||||
explicit ParityZero7bit(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
std::string execute(const std::string &exp, Transaction *transaction) override;
|
||||
static bool inplace(unsigned char *input, uint64_t input_len);
|
||||
};
|
||||
|
||||
|
@ -33,15 +33,17 @@ PhpArgsNames::PhpArgsNames(const std::string &a)
|
||||
}
|
||||
|
||||
|
||||
std::string PhpArgsNames::execute(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
void PhpArgsNames::execute(Transaction *t,
|
||||
ModSecStackString &val,
|
||||
ModSecStackString &out) {
|
||||
//Took the logic from php src code:
|
||||
//https://github.com/php/php-src/blob/master/main/php_variables.c
|
||||
//Function call PHPAPI void php_register_variable_ex(const char *var_name, zval *val, zval *track_vars_array)
|
||||
std::string value(val);
|
||||
std::string ret = "";
|
||||
if(value[0] == '[' || value[0] == '=') {
|
||||
return ret;
|
||||
out.assign(ret);
|
||||
return;
|
||||
}
|
||||
std::string::size_type i = 0;
|
||||
while(value[i] == ' ') {
|
||||
@ -74,7 +76,8 @@ std::string PhpArgsNames::execute(const std::string &val,
|
||||
char *tmp = &value[i];
|
||||
char *close_bra = strchr(tmp, ']');
|
||||
if(close_bra == NULL) {
|
||||
return ret;
|
||||
out.assign(ret);
|
||||
return;
|
||||
}
|
||||
int array_size = (int)(close_bra - start) + 1;
|
||||
if(array_size - i == 3 && value[i+1] == ' ') {
|
||||
@ -85,11 +88,13 @@ std::string PhpArgsNames::execute(const std::string &val,
|
||||
ret += value[i];
|
||||
}
|
||||
if(i >= val_size || value[i] != '[') {
|
||||
return ret;
|
||||
out.assign(ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
out.assign(ret);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,9 @@ class PhpArgsNames : public Transformation {
|
||||
public:
|
||||
explicit PhpArgsNames(const std::string &action);
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -32,21 +32,21 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string RemoveComments::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret;
|
||||
void RemoveComments::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
unsigned char *input;
|
||||
|
||||
input = reinterpret_cast<unsigned char *>
|
||||
(malloc(sizeof(char) * value.length()+1));
|
||||
(malloc(sizeof(char) * in.length()+1));
|
||||
|
||||
if (input == NULL) {
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(input, value.c_str(), value.length()+1);
|
||||
memcpy(input, in.c_str(), in.length()+1);
|
||||
|
||||
uint64_t input_len = value.size();
|
||||
uint64_t input_len = in.size();
|
||||
uint64_t i, j, incomment;
|
||||
|
||||
i = j = incomment = 0;
|
||||
@ -100,10 +100,8 @@ std::string RemoveComments::execute(const std::string &value,
|
||||
input[j++] = ' ';
|
||||
}
|
||||
|
||||
ret.assign(reinterpret_cast<char *>(input), j);
|
||||
out.assign(reinterpret_cast<char *>(input), j);
|
||||
free(input);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,10 +31,12 @@ namespace transformations {
|
||||
|
||||
class RemoveComments : public Transformation {
|
||||
public:
|
||||
explicit RemoveComments(const std::string &action) : Transformation(action) { }
|
||||
explicit RemoveComments(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;;
|
||||
};
|
||||
|
||||
|
||||
|
@ -30,48 +30,45 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
RemoveCommentsChar::RemoveCommentsChar(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
std::string RemoveCommentsChar::execute(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
void RemoveCommentsChar::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
int64_t i;
|
||||
std::string value(val);
|
||||
out = in;
|
||||
|
||||
i = 0;
|
||||
while (i < value.size()) {
|
||||
if (value.at(i) == '/'
|
||||
&& (i+1 < value.size()) && value.at(i+1) == '*') {
|
||||
value.erase(i, 2);
|
||||
} else if (value.at(i) == '*'
|
||||
&& (i+1 < value.size()) && value.at(i+1) == '/') {
|
||||
value.erase(i, 2);
|
||||
} else if (value.at(i) == '<'
|
||||
&& (i+1 < value.size())
|
||||
&& value.at(i+1) == '!'
|
||||
&& (i+2 < value.size())
|
||||
&& value.at(i+2) == '-'
|
||||
&& (i+3 < value.size())
|
||||
&& value.at(i+3) == '-') {
|
||||
value.erase(i, 4);
|
||||
} else if (value.at(i) == '-'
|
||||
&& (i+1 < value.size()) && value.at(i+1) == '-'
|
||||
&& (i+2 < value.size()) && value.at(i+2) == '>') {
|
||||
value.erase(i, 3);
|
||||
} else if (value.at(i) == '-'
|
||||
&& (i+1 < value.size()) && value.at(i+1) == '-') {
|
||||
value.erase(i, 2);
|
||||
} else if (value.at(i) == '#') {
|
||||
value.erase(i, 1);
|
||||
while (i < out.size()) {
|
||||
if (out.at(i) == '/'
|
||||
&& (i+1 < out.size()) && out.at(i+1) == '*') {
|
||||
out.erase(i, 2);
|
||||
} else if (out.at(i) == '*'
|
||||
&& (i+1 < out.size()) && out.at(i+1) == '/') {
|
||||
out.erase(i, 2);
|
||||
} else if (out.at(i) == '<'
|
||||
&& (i+1 < out.size())
|
||||
&& out.at(i+1) == '!'
|
||||
&& (i+2 < out.size())
|
||||
&& out.at(i+2) == '-'
|
||||
&& (i+3 < out.size())
|
||||
&& out.at(i+3) == '-') {
|
||||
out.erase(i, 4);
|
||||
} else if (out.at(i) == '-'
|
||||
&& (i+1 < out.size()) && out.at(i+1) == '-'
|
||||
&& (i+2 < out.size()) && out.at(i+2) == '>') {
|
||||
out.erase(i, 3);
|
||||
} else if (out.at(i) == '-'
|
||||
&& (i+1 < out.size()) && out.at(i+1) == '-') {
|
||||
out.erase(i, 2);
|
||||
} else if (out.at(i) == '#') {
|
||||
out.erase(i, 1);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class RemoveCommentsChar : public Transformation {
|
||||
public:
|
||||
explicit RemoveCommentsChar(const std::string &action);
|
||||
explicit RemoveCommentsChar(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -33,21 +33,20 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string RemoveNulls::execute(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
void RemoveNulls::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
int64_t i;
|
||||
std::string value(val);
|
||||
out = in;
|
||||
|
||||
i = 0;
|
||||
while (i < value.size()) {
|
||||
if (value.at(i) == '\0') {
|
||||
value.erase(i, 1);
|
||||
while (i < out.size()) {
|
||||
if (out.at(i) == '\0') {
|
||||
out.erase(i, 1);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,8 +33,9 @@ class RemoveNulls : public Transformation {
|
||||
explicit RemoveNulls(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -31,22 +31,18 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
RemoveWhitespace::RemoveWhitespace(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
std::string RemoveWhitespace::execute(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
std::string value(val);
|
||||
|
||||
void RemoveWhitespace::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
out = in;
|
||||
int64_t i = 0;
|
||||
|
||||
// loop through all the chars
|
||||
while (i < value.size()) {
|
||||
while (i < out.size()) {
|
||||
// remove whitespaces and non breaking spaces (NBSP)
|
||||
if (isspace(value[i]) || (value[i] == NBSP)) {
|
||||
value.erase(i, 1);
|
||||
if (isspace(out[i]) || (out[i] == NBSP)) {
|
||||
out.erase(i, 1);
|
||||
} else {
|
||||
/* if the space is not a whitespace char, increment counter
|
||||
counter should not be incremented if a character is erased because
|
||||
@ -54,10 +50,9 @@ std::string RemoveWhitespace::execute(const std::string &val,
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class RemoveWhitespace : public Transformation {
|
||||
public:
|
||||
explicit RemoveWhitespace(const std::string &action);
|
||||
explicit RemoveWhitespace(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -31,24 +31,21 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
ReplaceComments::ReplaceComments(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
std::string ReplaceComments::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
void ReplaceComments::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
uint64_t i, j, incomment;
|
||||
|
||||
char *input = reinterpret_cast<char *>(
|
||||
malloc(sizeof(char) * value.size() + 1));
|
||||
memcpy(input, value.c_str(), value.size() + 1);
|
||||
input[value.size()] = '\0';
|
||||
malloc(sizeof(char) * in.size() + 1));
|
||||
memcpy(input, in.c_str(), in.size() + 1);
|
||||
input[in.size()] = '\0';
|
||||
|
||||
i = j = incomment = 0;
|
||||
while (i < value.size()) {
|
||||
while (i < in.size()) {
|
||||
if (incomment == 0) {
|
||||
if ((input[i] == '/') && (i + 1 < value.size())
|
||||
if ((input[i] == '/') && (i + 1 < in.size())
|
||||
&& (input[i + 1] == '*')) {
|
||||
incomment = 1;
|
||||
i += 2;
|
||||
@ -58,7 +55,7 @@ std::string ReplaceComments::execute(const std::string &value,
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
if ((input[i] == '*') && (i + 1 < value.size())
|
||||
if ((input[i] == '*') && (i + 1 < in.size())
|
||||
&& (input[i + 1] == '/')) {
|
||||
incomment = 0;
|
||||
i += 2;
|
||||
@ -74,13 +71,9 @@ std::string ReplaceComments::execute(const std::string &value,
|
||||
input[j++] = ' ';
|
||||
}
|
||||
|
||||
|
||||
std::string resp;
|
||||
resp.append(reinterpret_cast<char *>(input), j);
|
||||
out.append(reinterpret_cast<char *>(input), j);
|
||||
|
||||
free(input);
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class ReplaceComments : public Transformation {
|
||||
public:
|
||||
explicit ReplaceComments(const std::string &action) ;
|
||||
explicit ReplaceComments(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -30,29 +30,25 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
ReplaceNulls::ReplaceNulls(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
std::string ReplaceNulls::execute(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
void ReplaceNulls::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
int64_t i;
|
||||
std::string value(val);
|
||||
out = in;
|
||||
|
||||
i = 0;
|
||||
while (i < value.size()) {
|
||||
if (value.at(i) == '\0') {
|
||||
value.erase(i, 1);
|
||||
value.insert(i, " ", 1);
|
||||
while (i < out.size()) {
|
||||
if (out.at(i) == '\0') {
|
||||
out.erase(i, 1);
|
||||
out.insert(i, " ", 1);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class ReplaceNulls : public Transformation {
|
||||
public:
|
||||
explicit ReplaceNulls(const std::string &action) ;
|
||||
explicit ReplaceNulls(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -31,16 +31,18 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
Sha1::Sha1(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
|
||||
void Sha1::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
|
||||
auto a = Utils::Sha1::digest(
|
||||
std::string(in.c_str(), in.size())
|
||||
);
|
||||
|
||||
out.assign(a.c_str(), a.size());
|
||||
}
|
||||
|
||||
std::string Sha1::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
|
||||
return Utils::Sha1::digest(value);
|
||||
}
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class Sha1 : public Transformation {
|
||||
public:
|
||||
explicit Sha1(const std::string &action) ;
|
||||
explicit Sha1(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -41,27 +41,25 @@ namespace transformations {
|
||||
#define ISODIGIT(X) ((X >= '0') && (X <= '7'))
|
||||
#endif
|
||||
|
||||
std::string SqlHexDecode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret;
|
||||
void SqlHexDecode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
unsigned char *input;
|
||||
int size = 0;
|
||||
|
||||
input = reinterpret_cast<unsigned char *>
|
||||
(malloc(sizeof(char) * value.length()+1));
|
||||
(malloc(sizeof(char) * in.length()+1));
|
||||
|
||||
if (input == NULL) {
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(input, value.c_str(), value.length()+1);
|
||||
memcpy(input, in.c_str(), in.length()+1);
|
||||
|
||||
size = inplace(input, value.length());
|
||||
size = inplace(input, in.length());
|
||||
|
||||
ret.assign(reinterpret_cast<char *>(input), size);
|
||||
out.assign(reinterpret_cast<char *>(input), size);
|
||||
free(input);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class SqlHexDecode : public Transformation {
|
||||
public:
|
||||
explicit SqlHexDecode(const std::string &action) : Transformation(action) { }
|
||||
explicit SqlHexDecode(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
static int inplace(unsigned char *data, int len);
|
||||
|
||||
|
@ -70,11 +70,6 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string Transformation::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
return value;
|
||||
}
|
||||
|
||||
Transformation* Transformation::instantiate(std::string a) {
|
||||
IF_MATCH(base64DecodeExt) { return new Base64DecodeExt(a); }
|
||||
IF_MATCH(base64Decode) { return new Base64Decode(a); }
|
||||
|
@ -32,11 +32,12 @@ class Transformation : public Action {
|
||||
explicit Transformation(const std::string& _action)
|
||||
: Action(_action, RunTimeBeforeMatchAttemptKind) { }
|
||||
|
||||
Transformation(const std::string& _action, int kind)
|
||||
: Action(_action, kind) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override {
|
||||
// FIXME: this should be remove as soon as #1974 got fixed.
|
||||
out.assign(in.c_str(), in.length());
|
||||
}
|
||||
|
||||
static Transformation* instantiate(std::string a);
|
||||
};
|
||||
|
@ -31,37 +31,30 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string *Trim::ltrim(std::string *s) {
|
||||
void Trim::ltrim(ModSecStackString *s) {
|
||||
s->erase(s->begin(), std::find_if(s->begin(), s->end(),
|
||||
std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
std::string *Trim::rtrim(std::string *s) {
|
||||
void Trim::rtrim(ModSecStackString *s) {
|
||||
s->erase(std::find_if(s->rbegin(), s->rend(),
|
||||
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s->end());
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
std::string *Trim::trim(std::string *s) {
|
||||
return ltrim(rtrim(s));
|
||||
void Trim::trim(ModSecStackString *s) {
|
||||
rtrim(s);
|
||||
ltrim(s);
|
||||
}
|
||||
|
||||
|
||||
Trim::Trim(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
Trim::execute(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
std::string value(val);
|
||||
return *this->trim(&value);
|
||||
}
|
||||
void Trim::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
out = in;
|
||||
trim(&out);
|
||||
};
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -30,14 +30,16 @@ namespace transformations {
|
||||
|
||||
class Trim : public Transformation {
|
||||
public:
|
||||
explicit Trim(const std::string &action) ;
|
||||
explicit Trim(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
std::string *ltrim(std::string *s);
|
||||
std::string *rtrim(std::string *s);
|
||||
std::string *trim(std::string *s);
|
||||
void ltrim(ModSecStackString *s);
|
||||
void rtrim(ModSecStackString *s);
|
||||
void trim(ModSecStackString *s);
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -32,17 +32,13 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
void TrimLeft::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
out = in;
|
||||
ltrim(&out);
|
||||
};
|
||||
|
||||
TrimLeft::TrimLeft(const std::string &action)
|
||||
: Trim(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
std::string TrimLeft::execute(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
std::string value(val);
|
||||
return *ltrim(&value);
|
||||
}
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
|
@ -31,10 +31,12 @@ namespace transformations {
|
||||
|
||||
class TrimLeft : public Trim {
|
||||
public:
|
||||
explicit TrimLeft(const std::string &action) ;
|
||||
explicit TrimLeft(const std::string &action)
|
||||
: Trim(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -31,16 +31,13 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
TrimRight::TrimRight(const std::string &action)
|
||||
: Trim(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
void TrimRight::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
out = in;
|
||||
rtrim(&out);
|
||||
};
|
||||
|
||||
std::string TrimRight::execute(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
std::string value(val);
|
||||
return *this->rtrim(&value);
|
||||
}
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
|
@ -31,10 +31,12 @@ namespace transformations {
|
||||
|
||||
class TrimRight : public Trim {
|
||||
public:
|
||||
explicit TrimRight(const std::string &action) ;
|
||||
explicit TrimRight(const std::string &action)
|
||||
: Trim(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -27,22 +27,17 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
UpperCase::UpperCase(const std::string &a)
|
||||
: Transformation(a) {
|
||||
}
|
||||
|
||||
std::string UpperCase::execute(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
std::string value(val);
|
||||
void UpperCase::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
std::locale loc;
|
||||
|
||||
for (std::string::size_type i=0; i < value.length(); ++i) {
|
||||
value[i] = std::toupper(value[i], loc);
|
||||
out.reserve(in.size());
|
||||
for (std::string::size_type i=0; i < in.size(); ++i) {
|
||||
out += std::toupper(in[i], loc);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
||||
|
@ -32,10 +32,12 @@ namespace transformations {
|
||||
|
||||
class UpperCase : public Transformation {
|
||||
public:
|
||||
explicit UpperCase(const std::string &action) ;
|
||||
explicit UpperCase(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -32,30 +32,22 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
UrlDecode::UrlDecode(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
std::string UrlDecode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
void UrlDecode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
unsigned char *val(NULL);
|
||||
int invalid_count = 0;
|
||||
int changed;
|
||||
|
||||
val = (unsigned char *) malloc(sizeof(char) * value.size() + 1);
|
||||
memcpy(val, value.c_str(), value.size() + 1);
|
||||
val[value.size()] = '\0';
|
||||
val = (unsigned char *) malloc(sizeof(char) * in.size() + 1);
|
||||
memcpy(val, in.c_str(), in.size() + 1);
|
||||
val[in.size()] = '\0';
|
||||
|
||||
int size = utils::urldecode_nonstrict_inplace(val, value.size(),
|
||||
int size = utils::urldecode_nonstrict_inplace(val, in.size(),
|
||||
&invalid_count, &changed);
|
||||
std::string out;
|
||||
|
||||
out.append((const char *)val, size);
|
||||
|
||||
free(val);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,10 +32,12 @@ namespace transformations {
|
||||
|
||||
class UrlDecode : public Transformation {
|
||||
public:
|
||||
explicit UrlDecode(const std::string &action) ;
|
||||
explicit UrlDecode(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
};
|
||||
|
||||
} // namespace transformations
|
||||
|
@ -38,26 +38,24 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string UrlDecodeUni::execute(const std::string &value,
|
||||
Transaction *t) {
|
||||
std::string ret;
|
||||
void UrlDecodeUni::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
unsigned char *input;
|
||||
|
||||
input = reinterpret_cast<unsigned char *>
|
||||
(malloc(sizeof(char) * value.length()+1));
|
||||
(malloc(sizeof(char) * in.length()+1));
|
||||
|
||||
if (input == NULL) {
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(input, value.c_str(), value.length()+1);
|
||||
memcpy(input, in.c_str(), in.length()+1);
|
||||
|
||||
size_t i = inplace(input, value.length(), t);
|
||||
size_t i = inplace(input, in.length(), t);
|
||||
|
||||
ret.assign(reinterpret_cast<char *>(input), i);
|
||||
out.assign(reinterpret_cast<char *>(input), i);
|
||||
free(input);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,9 +31,13 @@ namespace transformations {
|
||||
|
||||
class UrlDecodeUni : public Transformation {
|
||||
public:
|
||||
explicit UrlDecodeUni(const std::string &action) : Transformation(action) { }
|
||||
explicit UrlDecodeUni(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
std::string execute(const std::string &exp, Transaction *transaction) override;
|
||||
static int inplace(unsigned char *input, uint64_t input_len,
|
||||
Transaction *transaction);
|
||||
};
|
||||
|
@ -31,12 +31,6 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
UrlEncode::UrlEncode(const std::string &action)
|
||||
: Transformation(action) {
|
||||
this->action_kind = 1;
|
||||
}
|
||||
|
||||
|
||||
std::string UrlEncode::url_enc(const char *input,
|
||||
unsigned int input_len, int *changed) {
|
||||
char *rval, *d;
|
||||
@ -87,13 +81,13 @@ std::string UrlEncode::url_enc(const char *input,
|
||||
}
|
||||
|
||||
|
||||
std::string UrlEncode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
void UrlEncode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
int changed;
|
||||
|
||||
std::string ret = url_enc(value.c_str(), value.size(), &changed);
|
||||
|
||||
return ret;
|
||||
std::string ret = url_enc(in.c_str(), in.size(), &changed);
|
||||
out.assign(ret.c_str(), ret.size());
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,10 +30,12 @@ namespace transformations {
|
||||
|
||||
class UrlEncode : public Transformation {
|
||||
public:
|
||||
explicit UrlEncode(const std::string &action) ;
|
||||
explicit UrlEncode(const std::string &action)
|
||||
: Transformation(action) { };
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
static std::string url_enc(const char *input,
|
||||
unsigned int input_len, int *changed);
|
||||
|
@ -33,31 +33,31 @@ namespace actions {
|
||||
namespace transformations {
|
||||
|
||||
|
||||
std::string Utf8ToUnicode::execute(const std::string &value,
|
||||
Transaction *transaction) {
|
||||
std::string ret;
|
||||
void Utf8ToUnicode::execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) {
|
||||
|
||||
unsigned char *input;
|
||||
int changed = 0;
|
||||
char *out;
|
||||
char *out2;
|
||||
|
||||
input = reinterpret_cast<unsigned char *>
|
||||
(malloc(sizeof(char) * value.length()+1));
|
||||
(malloc(sizeof(char) * in.length()+1));
|
||||
|
||||
if (input == NULL) {
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(input, value.c_str(), value.length()+1);
|
||||
memset(input, '\0', in.length()+1);
|
||||
memcpy(input, in.c_str(), in.length()+1);
|
||||
|
||||
out = inplace(input, value.size() + 1, &changed);
|
||||
out2 = inplace(input, in.size() + 1, &changed);
|
||||
if (out2 != NULL) {
|
||||
out.assign(reinterpret_cast<char *>(out2),
|
||||
strlen(reinterpret_cast<char *>(out2)));
|
||||
free(out2);
|
||||
}
|
||||
free(input);
|
||||
if (out != NULL) {
|
||||
ret.assign(reinterpret_cast<char *>(out),
|
||||
strlen(reinterpret_cast<char *>(out)));
|
||||
free(out);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,10 +35,13 @@ namespace transformations {
|
||||
|
||||
class Utf8ToUnicode : public Transformation {
|
||||
public:
|
||||
explicit Utf8ToUnicode(const std::string &action) : Transformation(action) { }
|
||||
explicit Utf8ToUnicode(const std::string &action)
|
||||
: Transformation(action) { }
|
||||
|
||||
std::string execute(const std::string &exp,
|
||||
Transaction *transaction) override;
|
||||
|
||||
void execute(Transaction *t,
|
||||
ModSecStackString &in,
|
||||
ModSecStackString &out) override;
|
||||
|
||||
static char *inplace(unsigned char *input, uint64_t input_len,
|
||||
int *changed);
|
||||
|
@ -439,7 +439,11 @@ std::string Lua::applyTransformations(lua_State *L, Transaction *t,
|
||||
"t:" + std::string(name));
|
||||
// FIXME: transformation is not yet returning null.
|
||||
if (tfn) {
|
||||
newVar = tfn->execute(newVar, t);
|
||||
ModSecStackString in;
|
||||
ModSecStackString out;
|
||||
in.assign(newVar.c_str(), newVar.size());
|
||||
tfn->execute(t, in, out);
|
||||
newVar.assign(out.c_str(), out.size());
|
||||
} else {
|
||||
ms_dbg_a(t, 1,
|
||||
"SecRuleScript: Invalid transformation function: " \
|
||||
@ -461,7 +465,11 @@ std::string Lua::applyTransformations(lua_State *L, Transaction *t,
|
||||
|
||||
// FIXME: transformation is not yet returning null.
|
||||
if (tfn) {
|
||||
newVar = tfn->execute(newVar, t);
|
||||
ModSecStackString in;
|
||||
ModSecStackString out;
|
||||
in.assign(newVar.c_str(), newVar.size());
|
||||
tfn->execute(t, in, out);
|
||||
newVar.assign(out.c_str(), out.size());
|
||||
delete tfn;
|
||||
} else {
|
||||
ms_dbg_a(t, 1, "SecRuleScript: Invalid transformation function: " \
|
||||
|
@ -305,7 +305,9 @@ int ModSecurity::processContentOffset(const char *content, size_t len,
|
||||
|
||||
while (!trans.empty()) {
|
||||
modsecurity::actions::transformations::Transformation *t;
|
||||
std::string varValueRes;
|
||||
ModSecStackString in;
|
||||
ModSecStackString out;
|
||||
|
||||
yajl_gen_map_open(g);
|
||||
yajl_gen_string(g,
|
||||
reinterpret_cast<const unsigned char*>("transformation"),
|
||||
@ -317,8 +319,9 @@ int ModSecurity::processContentOffset(const char *content, size_t len,
|
||||
|
||||
t = modsecurity::actions::transformations::Transformation::instantiate(
|
||||
trans.back().str().c_str());
|
||||
varValueRes = t->execute(varValue, NULL);
|
||||
varValue.assign(varValueRes);
|
||||
in.assign(varValue.c_str());
|
||||
t->execute(NULL, in, out);
|
||||
varValue.assign(out.c_str());
|
||||
trans.pop_back();
|
||||
|
||||
yajl_gen_string(g, reinterpret_cast<const unsigned char*>("value"),
|
||||
|
@ -19,6 +19,9 @@
|
||||
#include "modsecurity/modsecurity.h"
|
||||
#include "modsecurity/transaction.h"
|
||||
#include "src/utils/string.h"
|
||||
#include "src/actions/tag.h"
|
||||
#include "modsecurity/rule_with_actions.h"
|
||||
|
||||
|
||||
namespace modsecurity {
|
||||
|
||||
@ -94,4 +97,123 @@ std::string RuleMessage::log(const RuleMessage *rm, int props, int code) {
|
||||
}
|
||||
|
||||
|
||||
} // namespace modsecurity
|
||||
RuleWithActions *RuleMessage::getRule() const {
|
||||
return m_rule;
|
||||
}
|
||||
|
||||
|
||||
void RuleMessage::setRule(RuleWithActions *rule) {
|
||||
m_rule = rule;
|
||||
}
|
||||
|
||||
|
||||
bool RuleMessage::isSettle() const {
|
||||
return m_rule != nullptr;
|
||||
}
|
||||
|
||||
|
||||
int RuleMessage::getRuleId() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getId();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int RuleMessage::getPhase() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getPhase();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
std::string RuleMessage::getFileName() const {
|
||||
if (m_rule) {
|
||||
return *m_rule->getFileName().get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
int RuleMessage::getLineNumber() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getLineNumber();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
std::string RuleMessage::getRev() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getRevision();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
std::string RuleMessage::getVer() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getVersion();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
int RuleMessage::getMaturity() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getMaturity();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int RuleMessage::getAccuracy() const {
|
||||
if (m_rule) {
|
||||
return m_rule->getAccuracy();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
std::string RuleMessage::getClientIpAddress() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_clientIpAddress.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
std::string RuleMessage::getServerIpAddress() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_serverIpAddress.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
std::string RuleMessage::getRequestId() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_id.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
std::string RuleMessage::getUri() const {
|
||||
if (m_transaction) {
|
||||
return *m_transaction->m_uri_no_query_string_decoded.get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
bool RuleMessage::isDisruptive() const {
|
||||
if (m_rule) {
|
||||
return m_rule->hasDisruptiveAction();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
} // namespace modsecurity
|
||||
|
@ -360,62 +360,35 @@ void RuleWithActions::executeAction(Transaction *trans,
|
||||
}
|
||||
|
||||
|
||||
inline void RuleWithActions::executeTransformation(
|
||||
actions::transformations::Transformation *a,
|
||||
std::shared_ptr<std::string> *value,
|
||||
Transaction *trans,
|
||||
TransformationResults *ret,
|
||||
std::string *path) const {
|
||||
|
||||
std::string *oldValue = (*value).get();
|
||||
std::string newValue = a->execute(*oldValue, trans);
|
||||
|
||||
if (newValue != *oldValue) {
|
||||
std::shared_ptr<std::string> u(new std::string(newValue));
|
||||
if (m_containsMultiMatchAction) {
|
||||
ret->push_back(std::make_pair(u, a->m_name));
|
||||
}
|
||||
*value = u;
|
||||
}
|
||||
|
||||
if (path->empty()) {
|
||||
path->append(*a->m_name.get());
|
||||
} else {
|
||||
path->append("," + *a->m_name.get());
|
||||
}
|
||||
|
||||
ms_dbg_a(trans, 9, "Transformation " + \
|
||||
*a->m_name.get() + ": \"" + \
|
||||
utils::string::limitTo(80, newValue) + "\"");
|
||||
}
|
||||
|
||||
void RuleWithActions::executeTransformations(
|
||||
Transaction *trans,
|
||||
const std::string &in,
|
||||
TransformationResults &ret) {
|
||||
TransformationsResults &results) {
|
||||
int none = 0;
|
||||
|
||||
ModSecStackString ssin;
|
||||
ssin.assign(in.c_str());
|
||||
|
||||
TransformationResult a = TransformationResult(&ssin);
|
||||
results.push_back(a);
|
||||
|
||||
|
||||
std::string path("");
|
||||
std::shared_ptr<std::string> value =
|
||||
std::shared_ptr<std::string>(new std::string(in));
|
||||
|
||||
if (hasMultimatchAction()) {
|
||||
/* keep the original value */
|
||||
ret.push_back(std::make_pair(
|
||||
std::shared_ptr<std::string>(new std::string(*value)),
|
||||
std::shared_ptr<std::string>(new std::string(path))));
|
||||
}
|
||||
|
||||
for (Action *a : getTransformationPtr()) {
|
||||
if (a->m_isNone) {
|
||||
for (Action *action : getTransformationPtr()) {
|
||||
if (action->m_isNone) {
|
||||
none++;
|
||||
}
|
||||
}
|
||||
|
||||
for (Transformation *a : getTransformationPtr()) {
|
||||
for (Transformation *t : getTransformationPtr()) {
|
||||
if (none == 0) {
|
||||
executeTransformation(a, &value, trans, &ret, &path);
|
||||
executeTransformation(trans, &results, t);
|
||||
}
|
||||
if (a->m_isNone) {
|
||||
if (t->m_isNone) {
|
||||
none--;
|
||||
}
|
||||
}
|
||||
@ -427,8 +400,8 @@ void RuleWithActions::executeTransformations(
|
||||
if (m_ruleId != b.first) {
|
||||
continue;
|
||||
}
|
||||
Transformation *a = dynamic_cast<Transformation*>(b.second.get());
|
||||
if (a->m_isNone) {
|
||||
Transformation *t = dynamic_cast<Transformation*>(b.second.get());
|
||||
if (t->m_isNone) {
|
||||
none++;
|
||||
}
|
||||
}
|
||||
@ -438,26 +411,61 @@ void RuleWithActions::executeTransformations(
|
||||
if (m_ruleId != b.first) {
|
||||
continue;
|
||||
}
|
||||
Transformation *a = dynamic_cast<Transformation*>(b.second.get());
|
||||
Transformation *t = dynamic_cast<Transformation*>(b.second.get());
|
||||
if (none == 0) {
|
||||
executeTransformation(a, &value, trans, &ret, &path);
|
||||
executeTransformation(trans, &results, t);
|
||||
}
|
||||
if (a->m_isNone) {
|
||||
if (t->m_isNone) {
|
||||
none--;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_containsMultiMatchAction == true) {
|
||||
/*
|
||||
if (hasMultimatchAction() == true) {
|
||||
ms_dbg_a(trans, 9, "multiMatch is enabled. " \
|
||||
+ std::to_string(ret.size()) + \
|
||||
+ std::to_string(results.size()) + \
|
||||
" values to be tested.");
|
||||
} else {
|
||||
results.pop_front();
|
||||
results.push_back(TransformationResult(&ssin));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (!m_containsMultiMatchAction) {
|
||||
ret.push_back(std::make_pair(
|
||||
std::shared_ptr<std::string>(new std::string(*value)),
|
||||
std::shared_ptr<std::string>(new std::string(path))));
|
||||
}
|
||||
|
||||
|
||||
void RuleWithActions::executeTransformation(
|
||||
Transaction *transaction,
|
||||
TransformationsResults *ret,
|
||||
Transformation *transformation) {
|
||||
executeTransformation(
|
||||
transaction,
|
||||
*ret->back().getAfter(),
|
||||
ret,
|
||||
transformation
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void RuleWithActions::executeTransformation(
|
||||
Transaction *transaction,
|
||||
ModSecStackString in,
|
||||
TransformationsResults *ret,
|
||||
Transformation *transformation) {
|
||||
|
||||
ModSecStackString out;
|
||||
transformation->execute(transaction, in, out);
|
||||
|
||||
ms_dbg_a(transaction, 9, " T (" + std::to_string(ret->size() - 1) + ") " + \
|
||||
*transformation->m_name.get() + ": \"" + \
|
||||
utils::string::limitTo(80, out.c_str()) + "\"");
|
||||
|
||||
ret->push_back(
|
||||
TransformationResult(
|
||||
&out,
|
||||
transformation->m_name.get()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -291,15 +291,22 @@ bool RuleWithOperator::evaluate(Transaction *trans) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TransformationResults values;
|
||||
TransformationsResults transformationsResults;
|
||||
|
||||
executeTransformations(trans, value, values);
|
||||
executeTransformations(trans, value, transformationsResults);
|
||||
|
||||
for (const auto &valueTemp : values) {
|
||||
auto iter = transformationsResults.begin();
|
||||
if (!hasMultimatchAction()) {
|
||||
iter = transformationsResults.end();
|
||||
std::advance(iter, -1);
|
||||
}
|
||||
while (iter != transformationsResults.end()) {
|
||||
bool ret;
|
||||
std::string valueAfterTrans = std::move(*valueTemp.first);
|
||||
auto &valueTemp = *iter;
|
||||
// FIXME: this copy is not necessary.
|
||||
std::string *valueAfterTrans = new std::string(valueTemp.getAfter()->c_str());
|
||||
|
||||
ret = executeOperatorAt(trans, key, valueAfterTrans);
|
||||
ret = executeOperatorAt(trans, key, *valueAfterTrans);
|
||||
|
||||
if (ret == true) {
|
||||
trans->messageGetLast()->m_match = m_operator->resolveMatchMessage(trans,
|
||||
@ -308,14 +315,28 @@ bool RuleWithOperator::evaluate(Transaction *trans) {
|
||||
for (auto &i : v->getOrigin()) {
|
||||
trans->messageGetLast()->m_reference.append(i->toText());
|
||||
}
|
||||
auto iter2 = transformationsResults.begin();
|
||||
while (iter2 != transformationsResults.end()) {
|
||||
if (iter2->getTransformationName()) {
|
||||
trans->messageGetLast()->m_reference.append(*iter2->getTransformationName());
|
||||
}
|
||||
/*
|
||||
if (iter == iter2) {
|
||||
break;
|
||||
} else {
|
||||
trans->messageGetLast()->m_reference.append("--");
|
||||
}
|
||||
*/
|
||||
iter2++;
|
||||
}
|
||||
|
||||
trans->messageGetLast()->m_reference.append(*valueTemp.second);
|
||||
|
||||
updateMatchedVars(trans, key, valueAfterTrans);
|
||||
updateMatchedVars(trans, key, *valueAfterTrans);
|
||||
executeActionsIndependentOfChainedRuleResult(trans);
|
||||
|
||||
globalRet = true;
|
||||
}
|
||||
delete valueAfterTrans;
|
||||
iter++;
|
||||
}
|
||||
delete v;
|
||||
v = NULL;
|
||||
|
84
src/rules.cc
Normal file
84
src/rules.cc
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.h"
|
||||
#include "src/rule_with_actions.h"
|
||||
|
||||
|
||||
namespace modsecurity {
|
||||
|
||||
|
||||
int Rules::append(Rules *from, const std::vector<int64_t> &ids, std::ostringstream *err) {
|
||||
size_t j = 0;
|
||||
for (; j < from->size(); j++) {
|
||||
RuleWithActions *rule = dynamic_cast<RuleWithActions*>(from->at(j).get());
|
||||
if (rule && std::binary_search(ids.begin(), ids.end(), rule->getId())) {
|
||||
if (err != NULL) {
|
||||
*err << "Rule id: " << std::to_string(rule->getId()) \
|
||||
<< " is duplicated" << std::endl;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
m_rules.insert(m_rules.end(), from->m_rules.begin(), from->m_rules.end());
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
bool Rules::insert(std::shared_ptr<Rule> rule) {
|
||||
return insert(rule, nullptr, nullptr);
|
||||
}
|
||||
|
||||
|
||||
bool Rules::insert(std::shared_ptr<Rule> rule, const std::vector<int64_t> *ids, std::ostringstream *err) {
|
||||
RuleWithActions*r = dynamic_cast<RuleWithActions*>(rule.get());
|
||||
if (r && ids != nullptr && err != nullptr
|
||||
&& std::binary_search(ids->begin(), ids->end(), r->getId())) {
|
||||
if (err != NULL) {
|
||||
*err << "Rule id: " << std::to_string(r->getId()) \
|
||||
<< " is duplicated" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
m_rules.push_back(rule);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
size_t Rules::size() {
|
||||
return m_rules.size();
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Rule> Rules::operator[](int index) {
|
||||
return m_rules[index];
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Rule> Rules::at(int index) {
|
||||
return m_rules[index];
|
||||
}
|
||||
|
||||
|
||||
void Rules::dump() {
|
||||
for (int j = 0; j < m_rules.size(); j++) {
|
||||
std::cout << " Rule ID: " << m_rules.at(j)->getReference();
|
||||
std::cout << "--" << m_rules.at(j) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace modsecurity
|
||||
|
@ -49,7 +49,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "",
|
||||
"debug_log": "\\[9\\] Transformation t:trim: \"test",
|
||||
"debug_log": "\\[9\\] T \\(0\\) t:trim: \"test",
|
||||
"error_log": "",
|
||||
"http_code": 403
|
||||
},
|
||||
@ -109,7 +109,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "",
|
||||
"debug_log": "\\[9\\] Transformation t:trim: \"test",
|
||||
"debug_log": "\\[9\\] T \\(0\\) t:trim: \"test",
|
||||
"error_log": "",
|
||||
"http_code": 302,
|
||||
"redirect_url": "http://www.google.com"
|
||||
@ -169,7 +169,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "",
|
||||
"debug_log": "\\[9\\] Transformation t:trim: \"test",
|
||||
"debug_log": "\\[9\\] T \\(0\\) t:trim: \"test",
|
||||
"error_log": "",
|
||||
"http_code": 306,
|
||||
"redirect_url": "http://www.google.com"
|
||||
@ -229,7 +229,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "",
|
||||
"debug_log": "\\[9\\] Transformation t:trim: \"test",
|
||||
"debug_log": "\\[9\\] T \\(0\\) t:trim: \"test",
|
||||
"error_log": "",
|
||||
"http_code": 500
|
||||
},
|
||||
@ -288,7 +288,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "",
|
||||
"debug_log": "\\[9\\] Transformation t:trim: \"test",
|
||||
"debug_log": "\\[9\\] T \\(0\\) t:trim: \"test",
|
||||
"error_log": "",
|
||||
"http_code": 500
|
||||
},
|
||||
@ -347,7 +347,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "",
|
||||
"debug_log": "\\[9\\] Transformation t:trim: \"test",
|
||||
"debug_log": "\\[9\\] T \\(0\\) t:trim: \"test",
|
||||
"error_log": "",
|
||||
"http_code": 500
|
||||
},
|
||||
|
@ -40,7 +40,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "",
|
||||
"debug_log": "\\[9\\] Transformation t:trim: \"test",
|
||||
"debug_log": "\\[9\\] T \\(0\\) t:trim: \"test",
|
||||
"error_log": "",
|
||||
"http_code": 403
|
||||
},
|
||||
@ -97,7 +97,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "",
|
||||
"debug_log": "\\[9\\] Transformation t:trim: \"test",
|
||||
"debug_log": "\\[9\\] T \\(0\\) t:trim: \"test",
|
||||
"error_log": "",
|
||||
"http_code": 403
|
||||
},
|
||||
@ -155,7 +155,7 @@
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "",
|
||||
"debug_log": "\\[9\\] Transformation t:trim: \"test",
|
||||
"debug_log": "\\[9\\] T \\(0\\) t:trim: \"test",
|
||||
"error_log": "",
|
||||
"http_code": 403
|
||||
},
|
||||
|
@ -48,7 +48,7 @@
|
||||
},
|
||||
"expected":{
|
||||
"audit_log":"",
|
||||
"debug_log":"Transformation t:lowercase: \"test2\"",
|
||||
"debug_log":"T \\(0\\) t:lowercase: \"test2\"",
|
||||
"error_log":""
|
||||
},
|
||||
"rules":[
|
||||
|
@ -31,7 +31,7 @@
|
||||
]
|
||||
},
|
||||
"expected":{
|
||||
"debug_log":"Transformation t:trim: \"no need.\""
|
||||
"debug_log":"T \\(0\\) t:trim: \"no need.\""
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
|
@ -51,7 +51,7 @@
|
||||
]
|
||||
},
|
||||
"expected":{
|
||||
"debug_log":"Transformation t:trim: \"small_text_file"
|
||||
"debug_log":"T \\(0\\) t:trim: \"small_text_file"
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
|
@ -51,7 +51,7 @@
|
||||
]
|
||||
},
|
||||
"expected":{
|
||||
"debug_log":"Transformation t:trim: \"filedata"
|
||||
"debug_log":"T \\(0\\) t:trim: \"filedata"
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
|
@ -90,8 +90,14 @@ void perform_unit_test(ModSecurityTest<UnitTest> *test, UnitTest *t,
|
||||
}
|
||||
delete op;
|
||||
} else if (t->type == "tfn") {
|
||||
modsecurity::ModSecStackString in;
|
||||
modsecurity::ModSecStackString out;
|
||||
std::string ret;
|
||||
in.assign(t->input.c_str(), t->input.size());
|
||||
Transformation *tfn = Transformation::instantiate("t:" + t->name);
|
||||
std::string ret = tfn->execute(t->input, NULL);
|
||||
tfn->execute(NULL, in, out);
|
||||
ret.assign(out.c_str(), out.size());
|
||||
|
||||
t->obtained = 1;
|
||||
t->obtainedOutput = ret;
|
||||
if (ret != t->output) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user