mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-13 13:26:01 +03:00
Add support for new operator rxGlobal
This commit is contained in:
parent
785958f9b5
commit
2672db103e
2
CHANGES
2
CHANGES
@ -1,6 +1,8 @@
|
|||||||
v3.x.y - YYYY-MMM-DD (to be released)
|
v3.x.y - YYYY-MMM-DD (to be released)
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
|
- Add support for new operator rxGlobal
|
||||||
|
[@martinhsv]
|
||||||
- Fix maxminddb link on FreeBSD
|
- Fix maxminddb link on FreeBSD
|
||||||
[Issue #2131 - @granalberto, @zimmerle]
|
[Issue #2131 - @granalberto, @zimmerle]
|
||||||
- Fix IP address logging in Section A
|
- Fix IP address logging in Section A
|
||||||
|
@ -171,6 +171,7 @@ TESTS+=test/test-cases/regression/operator-inpectFile.json
|
|||||||
TESTS+=test/test-cases/regression/operator-ipMatchFromFile.json
|
TESTS+=test/test-cases/regression/operator-ipMatchFromFile.json
|
||||||
TESTS+=test/test-cases/regression/operator-pm.json
|
TESTS+=test/test-cases/regression/operator-pm.json
|
||||||
TESTS+=test/test-cases/regression/operator-rx.json
|
TESTS+=test/test-cases/regression/operator-rx.json
|
||||||
|
TESTS+=test/test-cases/regression/operator-rxGlobal.json
|
||||||
TESTS+=test/test-cases/regression/operator-UnconditionalMatch.json
|
TESTS+=test/test-cases/regression/operator-UnconditionalMatch.json
|
||||||
TESTS+=test/test-cases/regression/operator-validate-byte-range.json
|
TESTS+=test/test-cases/regression/operator-validate-byte-range.json
|
||||||
TESTS+=test/test-cases/regression/operator-verifycc.json
|
TESTS+=test/test-cases/regression/operator-verifycc.json
|
||||||
@ -290,6 +291,7 @@ TESTS+=test/test-cases/secrules-language-tests/operators/noMatch.json
|
|||||||
TESTS+=test/test-cases/secrules-language-tests/operators/pmFromFile.json
|
TESTS+=test/test-cases/secrules-language-tests/operators/pmFromFile.json
|
||||||
TESTS+=test/test-cases/secrules-language-tests/operators/pm.json
|
TESTS+=test/test-cases/secrules-language-tests/operators/pm.json
|
||||||
TESTS+=test/test-cases/secrules-language-tests/operators/rx.json
|
TESTS+=test/test-cases/secrules-language-tests/operators/rx.json
|
||||||
|
TESTS+=test/test-cases/secrules-language-tests/operators/rxGlobal.json
|
||||||
TESTS+=test/test-cases/secrules-language-tests/operators/streq.json
|
TESTS+=test/test-cases/secrules-language-tests/operators/streq.json
|
||||||
TESTS+=test/test-cases/secrules-language-tests/operators/strmatch.json
|
TESTS+=test/test-cases/secrules-language-tests/operators/strmatch.json
|
||||||
TESTS+=test/test-cases/secrules-language-tests/operators/unconditionalMatch.json
|
TESTS+=test/test-cases/secrules-language-tests/operators/unconditionalMatch.json
|
||||||
|
@ -221,6 +221,7 @@ OPERATORS = \
|
|||||||
operators/rbl.cc \
|
operators/rbl.cc \
|
||||||
operators/rsub.cc \
|
operators/rsub.cc \
|
||||||
operators/rx.cc \
|
operators/rx.cc \
|
||||||
|
operators/rx_global.cc \
|
||||||
operators/str_eq.cc \
|
operators/str_eq.cc \
|
||||||
operators/str_match.cc \
|
operators/str_match.cc \
|
||||||
operators/validate_byte_range.cc \
|
operators/validate_byte_range.cc \
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "src/operators/rbl.h"
|
#include "src/operators/rbl.h"
|
||||||
#include "src/operators/rsub.h"
|
#include "src/operators/rsub.h"
|
||||||
#include "src/operators/rx.h"
|
#include "src/operators/rx.h"
|
||||||
|
#include "src/operators/rx_global.h"
|
||||||
#include "src/operators/str_eq.h"
|
#include "src/operators/str_eq.h"
|
||||||
#include "src/operators/str_match.h"
|
#include "src/operators/str_match.h"
|
||||||
#include "src/operators/validate_byte_range.h"
|
#include "src/operators/validate_byte_range.h"
|
||||||
@ -169,6 +170,7 @@ Operator *Operator::instantiate(std::string op, std::string param_str) {
|
|||||||
IF_MATCH(rbl) { return new Rbl(std::move(param)); }
|
IF_MATCH(rbl) { return new Rbl(std::move(param)); }
|
||||||
IF_MATCH(rsub) { return new Rsub(std::move(param)); }
|
IF_MATCH(rsub) { return new Rsub(std::move(param)); }
|
||||||
IF_MATCH(rx) { return new Rx(std::move(param)); }
|
IF_MATCH(rx) { return new Rx(std::move(param)); }
|
||||||
|
IF_MATCH(rxglobal) { return new RxGlobal(std::move(param)); }
|
||||||
IF_MATCH(streq) { return new StrEq(std::move(param)); }
|
IF_MATCH(streq) { return new StrEq(std::move(param)); }
|
||||||
IF_MATCH(strmatch) { return new StrMatch(std::move(param)); }
|
IF_MATCH(strmatch) { return new StrMatch(std::move(param)); }
|
||||||
IF_MATCH(validatebyterange) {
|
IF_MATCH(validatebyterange) {
|
||||||
|
85
src/operators/rx_global.cc
Normal file
85
src/operators/rx_global.cc
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* ModSecurity, http://www.modsecurity.org/
|
||||||
|
* Copyright (c) 2020 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 "src/operators/rx_global.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "src/operators/operator.h"
|
||||||
|
#include "modsecurity/rule.h"
|
||||||
|
#include "modsecurity/rule_message.h"
|
||||||
|
|
||||||
|
namespace modsecurity {
|
||||||
|
namespace operators {
|
||||||
|
|
||||||
|
|
||||||
|
bool RxGlobal::init(const std::string &arg, std::string *error) {
|
||||||
|
if (m_string->m_containsMacro == false) {
|
||||||
|
m_re = new Regex(m_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule,
|
||||||
|
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
|
||||||
|
Regex *re;
|
||||||
|
|
||||||
|
if (m_param.empty() && !m_string->m_containsMacro) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_string->m_containsMacro) {
|
||||||
|
std::string eparam(m_string->evaluate(transaction));
|
||||||
|
re = new Regex(eparam);
|
||||||
|
} else {
|
||||||
|
re = m_re;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Utils::SMatchCapture> captures;
|
||||||
|
re->searchGlobal(input, captures);
|
||||||
|
|
||||||
|
if (rule && rule->hasCaptureAction() && transaction) {
|
||||||
|
for (const Utils::SMatchCapture& capture : captures) {
|
||||||
|
const std::string capture_substring(input.substr(capture.m_offset,capture.m_length));
|
||||||
|
transaction->m_collections.m_tx_collection->storeOrUpdateFirst(
|
||||||
|
std::to_string(capture.m_group), capture_substring);
|
||||||
|
ms_dbg_a(transaction, 7, "Added regex subexpression TX." +
|
||||||
|
std::to_string(capture.m_group) + ": " + capture_substring);
|
||||||
|
transaction->m_matched.push_back(capture_substring);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto & capture : captures) {
|
||||||
|
logOffset(ruleMessage, capture.m_offset, capture.m_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_string->m_containsMacro) {
|
||||||
|
delete re;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (captures.size() > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace operators
|
||||||
|
} // namespace modsecurity
|
67
src/operators/rx_global.h
Normal file
67
src/operators/rx_global.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* ModSecurity, http://www.modsecurity.org/
|
||||||
|
* Copyright (c) 2020 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRC_OPERATORS_RX_GLOBAL_H_
|
||||||
|
#define SRC_OPERATORS_RX_GLOBAL_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
//#include <list>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "src/operators/operator.h"
|
||||||
|
#include "src/utils/regex.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace modsecurity {
|
||||||
|
using Utils::SMatch;
|
||||||
|
using Utils::regex_search;
|
||||||
|
using Utils::Regex;
|
||||||
|
|
||||||
|
namespace operators {
|
||||||
|
|
||||||
|
|
||||||
|
class RxGlobal : public Operator {
|
||||||
|
public:
|
||||||
|
/** @ingroup ModSecurity_Operator */
|
||||||
|
explicit RxGlobal(std::unique_ptr<RunTimeString> param)
|
||||||
|
: m_re(nullptr),
|
||||||
|
Operator("RxGlobal", std::move(param)) {
|
||||||
|
m_couldContainsMacro = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~RxGlobal() {
|
||||||
|
if (m_string->m_containsMacro == false && m_re != NULL) {
|
||||||
|
delete m_re;
|
||||||
|
m_re = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool evaluate(Transaction *transaction, RuleWithActions *rule,
|
||||||
|
const std::string& input,
|
||||||
|
std::shared_ptr<RuleMessage> ruleMessage) override;
|
||||||
|
|
||||||
|
bool init(const std::string &arg, std::string *error) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Regex *m_re;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace operators
|
||||||
|
} // namespace modsecurity
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SRC_OPERATORS_RX_GLOBAL_H_
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -132,6 +132,7 @@ class Driver;
|
|||||||
#include "src/operators/rbl.h"
|
#include "src/operators/rbl.h"
|
||||||
#include "src/operators/rsub.h"
|
#include "src/operators/rsub.h"
|
||||||
#include "src/operators/rx.h"
|
#include "src/operators/rx.h"
|
||||||
|
#include "src/operators/rx_global.h"
|
||||||
#include "src/operators/str_eq.h"
|
#include "src/operators/str_eq.h"
|
||||||
#include "src/operators/str_match.h"
|
#include "src/operators/str_match.h"
|
||||||
#include "src/operators/unconditional_match.h"
|
#include "src/operators/unconditional_match.h"
|
||||||
@ -455,6 +456,7 @@ using namespace modsecurity::operators;
|
|||||||
OPERATOR_RSUB "OPERATOR_RSUB"
|
OPERATOR_RSUB "OPERATOR_RSUB"
|
||||||
OPERATOR_RX_CONTENT_ONLY "Operator RX (content only)"
|
OPERATOR_RX_CONTENT_ONLY "Operator RX (content only)"
|
||||||
OPERATOR_RX "OPERATOR_RX"
|
OPERATOR_RX "OPERATOR_RX"
|
||||||
|
OPERATOR_RX_GLOBAL "OPERATOR_RX_GLOBAL"
|
||||||
OPERATOR_STR_EQ "OPERATOR_STR_EQ"
|
OPERATOR_STR_EQ "OPERATOR_STR_EQ"
|
||||||
OPERATOR_STR_MATCH "OPERATOR_STR_MATCH"
|
OPERATOR_STR_MATCH "OPERATOR_STR_MATCH"
|
||||||
OPERATOR_UNCONDITIONAL_MATCH "OPERATOR_UNCONDITIONAL_MATCH"
|
OPERATOR_UNCONDITIONAL_MATCH "OPERATOR_UNCONDITIONAL_MATCH"
|
||||||
@ -1037,6 +1039,10 @@ op_before_init:
|
|||||||
{
|
{
|
||||||
OPERATOR_CONTAINER($$, new operators::Rx(std::move($2)));
|
OPERATOR_CONTAINER($$, new operators::Rx(std::move($2)));
|
||||||
}
|
}
|
||||||
|
| OPERATOR_RX_GLOBAL run_time_string
|
||||||
|
{
|
||||||
|
OPERATOR_CONTAINER($$, new operators::RxGlobal(std::move($2)));
|
||||||
|
}
|
||||||
| OPERATOR_STR_EQ run_time_string
|
| OPERATOR_STR_EQ run_time_string
|
||||||
{
|
{
|
||||||
OPERATOR_CONTAINER($$, new operators::StrEq(std::move($2)));
|
OPERATOR_CONTAINER($$, new operators::StrEq(std::move($2)));
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -302,6 +302,7 @@ OPERATOR_PM (?i:@pm)
|
|||||||
OPERATOR_RBL (?i:@rbl)
|
OPERATOR_RBL (?i:@rbl)
|
||||||
OPERATOR_RSUB (?i:@rsub)
|
OPERATOR_RSUB (?i:@rsub)
|
||||||
OPERATOR_RX (?i:@rx)
|
OPERATOR_RX (?i:@rx)
|
||||||
|
OPERATOR_RX_GLOBAL (?i:@rxGlobal)
|
||||||
OPERATOR_STR_EQ (?i:@streq)
|
OPERATOR_STR_EQ (?i:@streq)
|
||||||
OPERATOR_STR_MATCH (?i:@strmatch)
|
OPERATOR_STR_MATCH (?i:@strmatch)
|
||||||
OPERATOR_UNCONDITIONAL_MATCH (?i:@unconditionalMatch)
|
OPERATOR_UNCONDITIONAL_MATCH (?i:@unconditionalMatch)
|
||||||
@ -1105,6 +1106,7 @@ EQUALS_MINUS (?i:=\-)
|
|||||||
{OPERATOR_PM} { BEGIN_PARAMETER(); return p::make_OPERATOR_PM(*driver.loc.back()); }
|
{OPERATOR_PM} { BEGIN_PARAMETER(); return p::make_OPERATOR_PM(*driver.loc.back()); }
|
||||||
{OPERATOR_RBL} { BEGIN_PARAMETER(); return p::make_OPERATOR_RBL( *driver.loc.back()); }
|
{OPERATOR_RBL} { BEGIN_PARAMETER(); return p::make_OPERATOR_RBL( *driver.loc.back()); }
|
||||||
{OPERATOR_RX} { BEGIN_PARAMETER(); return p::make_OPERATOR_RX(*driver.loc.back()); }
|
{OPERATOR_RX} { BEGIN_PARAMETER(); return p::make_OPERATOR_RX(*driver.loc.back()); }
|
||||||
|
{OPERATOR_RX_GLOBAL} { BEGIN_PARAMETER(); return p::make_OPERATOR_RX_GLOBAL(*driver.loc.back()); }
|
||||||
{OPERATOR_STR_EQ} { BEGIN_PARAMETER(); return p::make_OPERATOR_STR_EQ(*driver.loc.back()); }
|
{OPERATOR_STR_EQ} { BEGIN_PARAMETER(); return p::make_OPERATOR_STR_EQ(*driver.loc.back()); }
|
||||||
{OPERATOR_STR_MATCH} { BEGIN_PARAMETER(); return p::make_OPERATOR_STR_MATCH(*driver.loc.back()); }
|
{OPERATOR_STR_MATCH} { BEGIN_PARAMETER(); return p::make_OPERATOR_STR_MATCH(*driver.loc.back()); }
|
||||||
{OPERATOR_BEGINS_WITH} { BEGIN_PARAMETER(); return p::make_OPERATOR_BEGINS_WITH(*driver.loc.back()); }
|
{OPERATOR_BEGINS_WITH} { BEGIN_PARAMETER(); return p::make_OPERATOR_BEGINS_WITH(*driver.loc.back()); }
|
||||||
|
@ -33,6 +33,24 @@
|
|||||||
namespace modsecurity {
|
namespace modsecurity {
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
|
// Helper function to tell us if the current config indicates CRLF is a valid newline sequence
|
||||||
|
bool crlfIsNewline() {
|
||||||
|
int d = 0;
|
||||||
|
pcre_config(PCRE_CONFIG_NEWLINE, &d);
|
||||||
|
|
||||||
|
unsigned int option_bits = (d == 13)? PCRE_NEWLINE_CR :
|
||||||
|
(d == 10)? PCRE_NEWLINE_LF :
|
||||||
|
(d == (13<<8 | 10))? PCRE_NEWLINE_CRLF :
|
||||||
|
(d == -2)? PCRE_NEWLINE_ANYCRLF :
|
||||||
|
(d == -1)? PCRE_NEWLINE_ANY : 0;
|
||||||
|
|
||||||
|
bool crlf_is_newline =
|
||||||
|
option_bits == PCRE_NEWLINE_ANY ||
|
||||||
|
option_bits == PCRE_NEWLINE_CRLF ||
|
||||||
|
option_bits == PCRE_NEWLINE_ANYCRLF;
|
||||||
|
|
||||||
|
return crlf_is_newline;
|
||||||
|
}
|
||||||
|
|
||||||
Regex::Regex(const std::string& pattern_)
|
Regex::Regex(const std::string& pattern_)
|
||||||
: pattern(pattern_.empty() ? ".*" : pattern_) {
|
: pattern(pattern_.empty() ? ".*" : pattern_) {
|
||||||
@ -115,6 +133,64 @@ bool Regex::searchOneMatch(const std::string& s, std::vector<SMatchCapture>& cap
|
|||||||
return (rc > 0);
|
return (rc > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Regex::searchGlobal(const std::string& s, std::vector<SMatchCapture>& captures) const {
|
||||||
|
const char *subject = s.c_str();
|
||||||
|
|
||||||
|
bool prev_match_zero_length = false;
|
||||||
|
int startOffset = 0;
|
||||||
|
|
||||||
|
while (startOffset <= s.length()) {
|
||||||
|
int ovector[OVECCOUNT];
|
||||||
|
int pcre_options = 0;
|
||||||
|
if (prev_match_zero_length) {
|
||||||
|
pcre_options = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED;
|
||||||
|
}
|
||||||
|
int rc = pcre_exec(m_pc, m_pce, subject, s.length(), startOffset, pcre_options, ovector, OVECCOUNT);
|
||||||
|
|
||||||
|
if (rc > 0) {
|
||||||
|
size_t firstGroupForThisFullMatch = captures.size();
|
||||||
|
for (int i = 0; i < rc; i++) {
|
||||||
|
size_t start = ovector[2*i];
|
||||||
|
size_t end = ovector[2*i+1];
|
||||||
|
size_t len = end - start;
|
||||||
|
if (end > s.length()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SMatchCapture capture(firstGroupForThisFullMatch + i, start, len);
|
||||||
|
captures.push_back(capture);
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
if (len > 0) {
|
||||||
|
// normal case; next call to pcre_exec should start after the end of the last full match string
|
||||||
|
startOffset = end;
|
||||||
|
prev_match_zero_length = false;
|
||||||
|
} else {
|
||||||
|
// zero-length match; modify next match attempt to avoid infinite loop
|
||||||
|
prev_match_zero_length = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (prev_match_zero_length) {
|
||||||
|
// The n-1 search found a zero-length match, so we did a subsequent search
|
||||||
|
// with the special flags. That subsequent exec did not find a match, so now advance
|
||||||
|
// by one character (unless CRLF, then advance by two)
|
||||||
|
startOffset++;
|
||||||
|
if (crlfIsNewline() && (startOffset < s.length()) && (s[startOffset-1] == '\r')
|
||||||
|
&& (s[startOffset] == '\n')) {
|
||||||
|
startOffset++;
|
||||||
|
}
|
||||||
|
prev_match_zero_length = false;
|
||||||
|
} else {
|
||||||
|
// normal case; no match on most recent scan (with options=0). We are done.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (captures.size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
int Regex::search(const std::string& s, SMatch *match) const {
|
int Regex::search(const std::string& s, SMatch *match) const {
|
||||||
int ovector[OVECCOUNT];
|
int ovector[OVECCOUNT];
|
||||||
int ret = pcre_exec(m_pc, m_pce, s.c_str(),
|
int ret = pcre_exec(m_pc, m_pce, s.c_str(),
|
||||||
|
@ -70,6 +70,7 @@ class Regex {
|
|||||||
|
|
||||||
std::list<SMatch> searchAll(const std::string& s) const;
|
std::list<SMatch> searchAll(const std::string& s) const;
|
||||||
bool searchOneMatch(const std::string& s, std::vector<SMatchCapture>& captures) const;
|
bool searchOneMatch(const std::string& s, std::vector<SMatchCapture>& captures) const;
|
||||||
|
bool searchGlobal(const std::string& s, std::vector<SMatchCapture>& captures) const;
|
||||||
int search(const std::string &s, SMatch *match) const;
|
int search(const std::string &s, SMatch *match) const;
|
||||||
int search(const std::string &s) const;
|
int search(const std::string &s) const;
|
||||||
|
|
||||||
|
46
test/test-cases/regression/operator-rxGlobal.json
Normal file
46
test/test-cases/regression/operator-rxGlobal.json
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"enabled":1,
|
||||||
|
"version_min":300000,
|
||||||
|
"title":"Testing Operator :: @rxGlobal",
|
||||||
|
"client":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":123
|
||||||
|
},
|
||||||
|
"server":{
|
||||||
|
"ip":"200.249.12.31",
|
||||||
|
"port":80
|
||||||
|
},
|
||||||
|
"request":{
|
||||||
|
"headers":{
|
||||||
|
"Host":"localhost",
|
||||||
|
"User-Agent":"curl/7.38.0",
|
||||||
|
"Accept":"*/*",
|
||||||
|
"Content-Length": "27",
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
"uri":"/",
|
||||||
|
"method":"POST",
|
||||||
|
"body": [
|
||||||
|
"param1=value1¶m2=value2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"response":{
|
||||||
|
"headers":{
|
||||||
|
"Date":"Mon, 13 Jul 2015 20:02:41 GMT",
|
||||||
|
"Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT",
|
||||||
|
"Content-Type":"text/html"
|
||||||
|
},
|
||||||
|
"body":[
|
||||||
|
"no need."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"expected":{
|
||||||
|
"debug_log":"Executing operator \"RxGlobal"
|
||||||
|
},
|
||||||
|
"rules":[
|
||||||
|
"SecRuleEngine On",
|
||||||
|
"SecRule ARGS \"@rxGlobal (value1)\" \"id:1,phase:2,pass,t:trim\""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
Loading…
x
Reference in New Issue
Block a user