mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Merge commit 'e0a89a2fcd1d0dd4cc103fc054242e8e8b10b7bf' into dev
This commit is contained in:
commit
af902fc4ec
44 changed files with 8637 additions and 7832 deletions
|
|
@ -18,7 +18,7 @@ jobs:
|
|||
- {label: "wo yajl", opt: "--without-yajl" }
|
||||
- {label: "wo geoip", opt: "--without-geoip" }
|
||||
- {label: "wo lmdb", opt: "--without-lmdb" }
|
||||
- {label: "wo ssdeep", opt: "--without-ssdeep" }
|
||||
- {label: "with pcre2", opt: "--with-pcre2" }
|
||||
- {label: "wo lua", opt: "--without-lua" }
|
||||
- {label: "without maxmind", opt: "--without-maxmind" }
|
||||
steps:
|
||||
|
|
@ -26,7 +26,7 @@ jobs:
|
|||
run: |
|
||||
sudo add-apt-repository --yes ppa:maxmind/ppa
|
||||
sudo apt-get update -y -qq
|
||||
sudo apt-get install -y libfuzzy-dev libyajl-dev libgeoip-dev liblua5.2-dev liblmdb-dev cppcheck libmaxminddb-dev libcurl4-openssl-dev
|
||||
sudo apt-get install -y libfuzzy-dev libyajl-dev libgeoip-dev liblua5.2-dev liblmdb-dev cppcheck libmaxminddb-dev libcurl4-openssl-dev libpcre2-dev pcre2-utils
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
|
@ -46,7 +46,7 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-10.15]
|
||||
os: [macos-11]
|
||||
compiler: [clang]
|
||||
configure:
|
||||
- {label: "with parser generation", opt: "--enable-parser-generation" }
|
||||
|
|
@ -73,5 +73,3 @@ jobs:
|
|||
run: make -j `sysctl -n hw.logicalcpu`
|
||||
- name: check
|
||||
run: make check
|
||||
- name: check-static
|
||||
run: make check-static
|
||||
|
|
|
|||
|
|
@ -1,3 +1,32 @@
|
|||
v3.0.10 - 2023-Jul-25
|
||||
---------------------
|
||||
|
||||
- Fix: worst-case time in implementation of four transformations
|
||||
[Issue #2934 - @martinhsv]
|
||||
- Add TX synonym for MSC_PCRE_LIMITS_EXCEEDED
|
||||
[Issue #2901 - @airween]
|
||||
- Make MULTIPART_PART_HEADERS accessible to lua
|
||||
[Issue #2916 - @martinhsv]
|
||||
- Fix: Lua scripts cannot read whole collection at once
|
||||
[Issue #2900 - @udi-aharon, @airween, @martinhsv]
|
||||
- Fix: quoted Include config with wildcard
|
||||
[Issue #2905 - @wiseelf, @airween, @martinhsv]
|
||||
- Support isolated PCRE match limits
|
||||
[Issue #2736 - @brandonpayton, @martinhsv]
|
||||
- Fix: meta actions not applied if multiMatch in first rule of chain
|
||||
[Issue #2867, #2868 - @mlevogiannis, @martinhsv]
|
||||
- Fix: audit log may omit tags when multiMatch
|
||||
[Issue #2866 - @mlevogiannis]
|
||||
- Exclude CRLF from MULTIPART_PART_HEADER value
|
||||
[Issue #2870 - @airween, @martinhsv]
|
||||
- Configure: use AS_ECHO_N instead echo -n
|
||||
[Issue #2894 - @liudongmiao, @martinhsv]
|
||||
- Adjust position of memset from 2890
|
||||
[Issue #2891 - @mirkodziadzka-avi, @martinhsv]
|
||||
- Add test: empty lines in ipMatchFromFile test
|
||||
[Issue #2846 - @tomsommer]
|
||||
|
||||
|
||||
v3.0.9 - 2023-Apr-12
|
||||
--------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -424,9 +424,9 @@ echo " "
|
|||
echo "ModSecurity - ${MSC_GIT_VERSION} for $PLATFORM"
|
||||
echo " "
|
||||
echo " Mandatory dependencies"
|
||||
echo -n " + libInjection ...."
|
||||
AS_ECHO_N(" + libInjection ....")
|
||||
echo LIBINJECTION_VERSION
|
||||
echo -n " + SecLang tests ...."
|
||||
AS_ECHO_N(" + SecLang tests ....")
|
||||
echo SECLANG_TEST_VERSION
|
||||
|
||||
echo " "
|
||||
|
|
@ -439,7 +439,7 @@ if test "x$GEOIP_FOUND" = "x0" && test "x$MAXMIND_FOUND" = "x0"; then
|
|||
echo " + GeoIP/MaxMind ....not found"
|
||||
fi
|
||||
if test "x$GEOIP_FOUND" = "x1" || test "x$MAXMIND_FOUND" = "x1"; then
|
||||
echo -n " + GeoIP/MaxMind ....found "
|
||||
AS_ECHO_N(" + GeoIP/MaxMind ....found ")
|
||||
echo ""
|
||||
if test "x$MAXMIND_FOUND" = "x1"; then
|
||||
echo " * (MaxMind) v${MAXMIND_VERSION}"
|
||||
|
|
@ -460,7 +460,7 @@ if test "x$CURL_FOUND" = "x0"; then
|
|||
echo " + LibCURL ....not found"
|
||||
fi
|
||||
if test "x$CURL_FOUND" = "x1"; then
|
||||
echo -n " + LibCURL ....found "
|
||||
AS_ECHO_N(" + LibCURL ....found ")
|
||||
if ! test "x$CURL_VERSION" = "x"; then
|
||||
echo "v${CURL_VERSION}"
|
||||
else
|
||||
|
|
@ -478,7 +478,7 @@ if test "x$YAJL_FOUND" = "x0"; then
|
|||
echo " + YAJL ....not found"
|
||||
fi
|
||||
if test "x$YAJL_FOUND" = "x1"; then
|
||||
echo -n " + YAJL ....found "
|
||||
AS_ECHO_N(" + YAJL ....found ")
|
||||
if ! test "x$YAJL_VERSION" = "x"; then
|
||||
echo "v${YAJL_VERSION}"
|
||||
else
|
||||
|
|
@ -496,7 +496,7 @@ if test "x$LMDB_FOUND" = "x0"; then
|
|||
echo " + LMDB ....not found"
|
||||
fi
|
||||
if test "x$LMDB_FOUND" = "x1"; then
|
||||
echo -n " + LMDB ....found "
|
||||
AS_ECHO_N(" + LMDB ....found ")
|
||||
if ! test "x$LMDB_VERSION" = "x"; then
|
||||
echo "v${LMDB_VERSION}"
|
||||
else
|
||||
|
|
@ -514,7 +514,7 @@ if test "x$LIBXML2_FOUND" = "x0"; then
|
|||
echo " + LibXML2 ....not found"
|
||||
fi
|
||||
if test "x$LIBXML2_FOUND" = "x1"; then
|
||||
echo -n " + LibXML2 ....found "
|
||||
AS_ECHO_N(" + LibXML2 ....found ")
|
||||
if ! test "x$LIBXML2_VERSION" = "x"; then
|
||||
echo "v${LIBXML2_VERSION}"
|
||||
else
|
||||
|
|
@ -532,7 +532,7 @@ if test "x$SSDEEP_FOUND" = "x0"; then
|
|||
echo " + SSDEEP ....not found"
|
||||
fi
|
||||
if test "x$SSDEEP_FOUND" = "x1"; then
|
||||
echo -n " + SSDEEP ....found "
|
||||
AS_ECHO_N(" + SSDEEP ....found ")
|
||||
if ! test "x$SSDEEP_VERSION" = "x"; then
|
||||
echo "v${SSDEEP_VERSION}"
|
||||
else
|
||||
|
|
@ -549,7 +549,7 @@ if test "x$LUA_FOUND" = "x0"; then
|
|||
echo " + LUA ....not found"
|
||||
fi
|
||||
if test "x$LUA_FOUND" = "x1"; then
|
||||
echo -n " + LUA ....found "
|
||||
AS_ECHO_N(" + LUA ....found ")
|
||||
if ! test "x$LUA_VERSION" = "x"; then
|
||||
echo "v${LUA_VERSION}"
|
||||
else
|
||||
|
|
@ -567,7 +567,7 @@ if test "x$PCRE2_FOUND" = "x0"; then
|
|||
echo " + PCRE2 ....not found"
|
||||
fi
|
||||
if test "x$PCRE2_FOUND" = "x1"; then
|
||||
echo -n " + PCRE2 ....found "
|
||||
AS_ECHO_N(" + PCRE2 ....found ")
|
||||
if ! test "x$PCRE2_VERSION" = "x"; then
|
||||
echo "v${PCRE2_VERSION}"
|
||||
else
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ namespace modsecurity {
|
|||
|
||||
#define MODSECURITY_MAJOR "3"
|
||||
#define MODSECURITY_MINOR "0"
|
||||
#define MODSECURITY_PATCHLEVEL "9"
|
||||
#define MODSECURITY_PATCHLEVEL "10"
|
||||
#define MODSECURITY_TAG ""
|
||||
#define MODSECURITY_TAG_NUM "100"
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ namespace modsecurity {
|
|||
MODSECURITY_MINOR "." MODSECURITY_PATCHLEVEL \
|
||||
MODSECURITY_TAG
|
||||
|
||||
#define MODSECURITY_VERSION_NUM 3090100
|
||||
#define MODSECURITY_VERSION_NUM 30100100
|
||||
|
||||
#define MODSECURITY_CHECK_VERSION(a) (MODSECURITY_VERSION_NUM <= a)
|
||||
|
||||
|
|
|
|||
|
|
@ -379,6 +379,7 @@ class RulesSetProperties {
|
|||
from->m_responseBodyLimitAction,
|
||||
PropertyNotSetBodyLimitAction);
|
||||
|
||||
to->m_pcreMatchLimit.merge(&from->m_pcreMatchLimit);
|
||||
to->m_uploadFileLimit.merge(&from->m_uploadFileLimit);
|
||||
to->m_uploadFileMode.merge(&from->m_uploadFileMode);
|
||||
to->m_uploadDirectory.merge(&from->m_uploadDirectory);
|
||||
|
|
@ -470,6 +471,7 @@ class RulesSetProperties {
|
|||
ConfigDouble m_requestBodyLimit;
|
||||
ConfigDouble m_requestBodyNoFilesLimit;
|
||||
ConfigDouble m_responseBodyLimit;
|
||||
ConfigInt m_pcreMatchLimit;
|
||||
ConfigInt m_uploadFileLimit;
|
||||
ConfigInt m_uploadFileMode;
|
||||
DebugLog *m_debugLog;
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@ class TransactionAnchoredVariables {
|
|||
m_variableInboundDataError(t, "INBOUND_DATA_ERROR"),
|
||||
m_variableMatchedVar(t, "MATCHED_VAR"),
|
||||
m_variableMatchedVarName(t, "MATCHED_VAR_NAME"),
|
||||
m_variableMscPcreError(t, "MSC_PCRE_ERROR"),
|
||||
m_variableMscPcreLimitsExceeded(t, "MSC_PCRE_LIMITS_EXCEEDED"),
|
||||
m_variableMultipartBoundaryQuoted(t, "MULTIPART_BOUNDARY_QUOTED"),
|
||||
m_variableMultipartBoundaryWhiteSpace(t,
|
||||
"MULTIPART_BOUNDARY_WHITESPACE"),
|
||||
|
|
@ -219,6 +221,8 @@ class TransactionAnchoredVariables {
|
|||
AnchoredVariable m_variableInboundDataError;
|
||||
AnchoredVariable m_variableMatchedVar;
|
||||
AnchoredVariable m_variableMatchedVarName;
|
||||
AnchoredVariable m_variableMscPcreError;
|
||||
AnchoredVariable m_variableMscPcreLimitsExceeded;
|
||||
AnchoredVariable m_variableMultipartBoundaryQuoted;
|
||||
AnchoredVariable m_variableMultipartBoundaryWhiteSpace;
|
||||
AnchoredVariable m_variableMultipartCrlfLFLines;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2015 - 2023 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
|
||||
|
|
@ -15,12 +15,7 @@
|
|||
|
||||
#include "src/actions/transformations/remove_comments_char.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cctype>
|
||||
#include <locale>
|
||||
|
||||
#include "modsecurity/transaction.h"
|
||||
#include "src/actions/transformations/transformation.h"
|
||||
|
|
@ -37,39 +32,40 @@ RemoveCommentsChar::RemoveCommentsChar(const std::string &action)
|
|||
|
||||
std::string RemoveCommentsChar::evaluate(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
int64_t i;
|
||||
std::string value(val);
|
||||
size_t i = 0;
|
||||
std::string transformed_value;
|
||||
transformed_value.reserve(val.size());
|
||||
|
||||
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 < val.size()) {
|
||||
if (val.at(i) == '/'
|
||||
&& (i+1 < val.size()) && val.at(i+1) == '*') {
|
||||
i += 2;
|
||||
} else if (val.at(i) == '*'
|
||||
&& (i+1 < val.size()) && val.at(i+1) == '/') {
|
||||
i += 2;
|
||||
} else if (val.at(i) == '<'
|
||||
&& (i+1 < val.size())
|
||||
&& val.at(i+1) == '!'
|
||||
&& (i+2 < val.size())
|
||||
&& val.at(i+2) == '-'
|
||||
&& (i+3 < val.size())
|
||||
&& val.at(i+3) == '-') {
|
||||
i += 4;
|
||||
} else if (val.at(i) == '-'
|
||||
&& (i+1 < val.size()) && val.at(i+1) == '-'
|
||||
&& (i+2 < val.size()) && val.at(i+2) == '>') {
|
||||
i += 3;
|
||||
} else if (val.at(i) == '-'
|
||||
&& (i+1 < val.size()) && val.at(i+1) == '-') {
|
||||
i += 2;
|
||||
} else if (val.at(i) == '#') {
|
||||
i += 1;
|
||||
} else {
|
||||
transformed_value += val.at(i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
return transformed_value;
|
||||
}
|
||||
|
||||
} // namespace transformations
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2015 - 2023 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
|
||||
|
|
@ -17,12 +17,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cctype>
|
||||
#include <locale>
|
||||
|
||||
#include "modsecurity/transaction.h"
|
||||
#include "src/actions/transformations/transformation.h"
|
||||
|
|
@ -35,19 +30,20 @@ namespace transformations {
|
|||
|
||||
std::string RemoveNulls::evaluate(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
int64_t i;
|
||||
std::string value(val);
|
||||
size_t i = 0;
|
||||
std::string transformed_value;
|
||||
transformed_value.reserve(val.size());
|
||||
|
||||
i = 0;
|
||||
while (i < value.size()) {
|
||||
if (value.at(i) == '\0') {
|
||||
value.erase(i, 1);
|
||||
while (i < val.size()) {
|
||||
if (val.at(i) == '\0') {
|
||||
// do nothing; continue on to next char in original val
|
||||
} else {
|
||||
i++;
|
||||
transformed_value += val.at(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return value;
|
||||
return transformed_value;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2015 - 2023 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
|
||||
|
|
@ -15,12 +15,7 @@
|
|||
|
||||
#include "src/actions/transformations/remove_whitespace.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cctype>
|
||||
#include <locale>
|
||||
|
||||
#include "modsecurity/transaction.h"
|
||||
#include "src/actions/transformations/transformation.h"
|
||||
|
|
@ -37,28 +32,27 @@ RemoveWhitespace::RemoveWhitespace(const std::string &action)
|
|||
|
||||
std::string RemoveWhitespace::evaluate(const std::string &val,
|
||||
Transaction *transaction) {
|
||||
std::string value(val);
|
||||
std::string transformed_value;
|
||||
transformed_value.reserve(val.size());
|
||||
|
||||
int64_t i = 0;
|
||||
size_t i = 0;
|
||||
const char nonBreakingSpaces = 0xa0;
|
||||
const char nonBreakingSpaces2 = 0xc2;
|
||||
|
||||
// loop through all the chars
|
||||
while (i < value.size()) {
|
||||
while (i < val.size()) {
|
||||
// remove whitespaces and non breaking spaces (NBSP)
|
||||
if (std::isspace(static_cast<unsigned char>(value[i]))
|
||||
|| (value[i] == nonBreakingSpaces)
|
||||
|| value[i] == nonBreakingSpaces2) {
|
||||
value.erase(i, 1);
|
||||
if (std::isspace(static_cast<unsigned char>(val[i]))
|
||||
|| (val[i] == nonBreakingSpaces)
|
||||
|| val[i] == nonBreakingSpaces2) {
|
||||
// don't copy; continue on to next char in original val
|
||||
} else {
|
||||
/* if the space is not a whitespace char, increment counter
|
||||
counter should not be incremented if a character is erased because
|
||||
the index erased will be replaced by the following character */
|
||||
i++;
|
||||
transformed_value += val.at(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return value;
|
||||
return transformed_value;
|
||||
}
|
||||
|
||||
} // namespace transformations
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2015 - 2023 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
|
||||
|
|
@ -15,12 +15,7 @@
|
|||
|
||||
#include "src/actions/transformations/replace_nulls.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cctype>
|
||||
#include <locale>
|
||||
|
||||
#include "modsecurity/transaction.h"
|
||||
#include "src/actions/transformations/transformation.h"
|
||||
|
|
@ -43,8 +38,7 @@ std::string ReplaceNulls::evaluate(const std::string &val,
|
|||
i = 0;
|
||||
while (i < value.size()) {
|
||||
if (value.at(i) == '\0') {
|
||||
value.erase(i, 1);
|
||||
value.insert(i, " ", 1);
|
||||
value[i] = ' ';
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace backend {
|
|||
|
||||
#ifdef WITH_LMDB
|
||||
|
||||
LMDB::LMDB(std::string name) :
|
||||
LMDB::LMDB(const std::string &name) :
|
||||
Collection(name), m_env(NULL), isOpen(false) {}
|
||||
|
||||
int LMDB::txn_begin(unsigned int flags, MDB_txn **ret) {
|
||||
|
|
@ -60,7 +60,7 @@ void LMDB::string2val(const std::string& str, MDB_val *val) {
|
|||
}
|
||||
|
||||
|
||||
void LMDB::lmdb_debug(int rc, std::string op, std::string scope) {
|
||||
void LMDB::lmdb_debug(int rc, const std::string &op, const std::string &scope) {
|
||||
#ifndef LMDB_STDOUT_COUT
|
||||
return;
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class MDBEnvProvider {
|
|||
class LMDB :
|
||||
public Collection {
|
||||
public:
|
||||
explicit LMDB(std::string name);
|
||||
explicit LMDB(const std::string &name);
|
||||
void store(std::string key, std::string value) override;
|
||||
|
||||
bool storeOrUpdateFirst(const std::string &key,
|
||||
|
|
@ -122,7 +122,7 @@ class LMDB :
|
|||
private:
|
||||
int txn_begin(unsigned int flags, MDB_txn **ret);
|
||||
void string2val(const std::string& str, MDB_val *val);
|
||||
void inline lmdb_debug(int rc, std::string op, std::string scope);
|
||||
void inline lmdb_debug(int rc, const std::string &op, const std::string &scope);
|
||||
|
||||
MDB_env *m_env;
|
||||
MDB_dbi m_dbi;
|
||||
|
|
|
|||
|
|
@ -51,12 +51,38 @@ bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule,
|
|||
re = m_re;
|
||||
}
|
||||
|
||||
std::vector<Utils::SMatchCapture> captures;
|
||||
if (re->hasError()) {
|
||||
ms_dbg_a(transaction, 3, "Error with regular expression: \"" + re->pattern + "\"");
|
||||
return false;
|
||||
}
|
||||
re->searchOneMatch(input, captures);
|
||||
|
||||
Utils::RegexResult regex_result;
|
||||
std::vector<Utils::SMatchCapture> captures;
|
||||
|
||||
if (transaction && transaction->m_rules->m_pcreMatchLimit.m_set) {
|
||||
unsigned long match_limit = transaction->m_rules->m_pcreMatchLimit.m_value;
|
||||
regex_result = re->searchOneMatch(input, captures, match_limit);
|
||||
} else {
|
||||
regex_result = re->searchOneMatch(input, captures);
|
||||
}
|
||||
|
||||
// FIXME: DRY regex error reporting. This logic is currently duplicated in other operators.
|
||||
if (regex_result != Utils::RegexResult::Ok) {
|
||||
transaction->m_variableMscPcreError.set("1", transaction->m_variableOffset);
|
||||
|
||||
std::string regex_error_str = "OTHER";
|
||||
if (regex_result == Utils::RegexResult::ErrorMatchLimit) {
|
||||
regex_error_str = "MATCH_LIMIT";
|
||||
transaction->m_variableMscPcreLimitsExceeded.set("1", transaction->m_variableOffset);
|
||||
transaction->m_collections.m_tx_collection->storeOrUpdateFirst("MSC_PCRE_LIMITS_EXCEEDED", "1");
|
||||
ms_dbg_a(transaction, 7, "Set TX.MSC_PCRE_LIMITS_EXCEEDED to 1");
|
||||
}
|
||||
|
||||
ms_dbg_a(transaction, 1, "rx: regex error '" + regex_error_str + "' for pattern '" + re->pattern + "'");
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rule && rule->hasCaptureAction() && transaction) {
|
||||
for (const Utils::SMatchCapture& capture : captures) {
|
||||
|
|
|
|||
|
|
@ -51,8 +51,32 @@ bool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule,
|
|||
re = m_re;
|
||||
}
|
||||
|
||||
Utils::RegexResult regex_result;
|
||||
std::vector<Utils::SMatchCapture> captures;
|
||||
re->searchGlobal(input, captures);
|
||||
if (transaction && transaction->m_rules->m_pcreMatchLimit.m_set) {
|
||||
unsigned long match_limit = transaction->m_rules->m_pcreMatchLimit.m_value;
|
||||
regex_result = re->searchGlobal(input, captures, match_limit);
|
||||
} else {
|
||||
regex_result = re->searchGlobal(input, captures);
|
||||
}
|
||||
|
||||
// FIXME: DRY regex error reporting. This logic is currently duplicated in other operators.
|
||||
if (regex_result != Utils::RegexResult::Ok) {
|
||||
transaction->m_variableMscPcreError.set("1", transaction->m_variableOffset);
|
||||
|
||||
std::string regex_error_str = "OTHER";
|
||||
if (regex_result == Utils::RegexResult::ErrorMatchLimit) {
|
||||
regex_error_str = "MATCH_LIMIT";
|
||||
transaction->m_variableMscPcreLimitsExceeded.set("1", transaction->m_variableOffset);
|
||||
transaction->m_collections.m_tx_collection->storeOrUpdateFirst("MSC_PCRE_LIMITS_EXCEEDED", "1");
|
||||
ms_dbg_a(transaction, 7, "Set TX.MSC_PCRE_LIMITS_EXCEEDED to 1");
|
||||
}
|
||||
|
||||
ms_dbg_a(transaction, 1, "rxGlobal: regex error '" + regex_error_str + "' for pattern '" + re->pattern + "'");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (rule && rule->hasCaptureAction() && transaction) {
|
||||
for (const Utils::SMatchCapture& capture : captures) {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ Driver::~Driver() {
|
|||
}
|
||||
|
||||
|
||||
int Driver::addSecMarker(std::string marker, std::unique_ptr<std::string> fileName, int lineNumber) {
|
||||
int Driver::addSecMarker(const std::string& marker, std::unique_ptr<std::string> fileName, int lineNumber) {
|
||||
// FIXME: we might move this to the parser.
|
||||
for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {
|
||||
RuleMarker *r = new RuleMarker(marker, std::unique_ptr<std::string>(new std::string(*fileName)), lineNumber);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class Driver : public RulesSetProperties {
|
|||
|
||||
int addSecRule(std::unique_ptr<RuleWithActions> rule);
|
||||
int addSecAction(std::unique_ptr<RuleWithActions> rule);
|
||||
int addSecMarker(std::string marker, std::unique_ptr<std::string> fileName, int lineNumber);
|
||||
int addSecMarker(const std::string& marker, std::unique_ptr<std::string> fileName, int lineNumber);
|
||||
int addSecRuleScript(std::unique_ptr<RuleScript> rule);
|
||||
|
||||
bool scan_begin();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// A Bison parser, made by GNU Bison 3.7.6.
|
||||
// A Bison parser, made by GNU Bison 3.8.2.
|
||||
|
||||
// Locations for Bison parsers in C++
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// A Bison parser, made by GNU Bison 3.7.6.
|
||||
// A Bison parser, made by GNU Bison 3.8.2.
|
||||
|
||||
// Starting with Bison 3.2, this file is useless: the structure it
|
||||
// used to define is now defined in "location.hh".
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -184,6 +184,8 @@ class Driver;
|
|||
#include "src/variables/matched_vars.h"
|
||||
#include "src/variables/matched_vars_names.h"
|
||||
#include "src/variables/modsec_build.h"
|
||||
#include "src/variables/msc_pcre_error.h"
|
||||
#include "src/variables/msc_pcre_limits_exceeded.h"
|
||||
#include "src/variables/multipart_boundary_quoted.h"
|
||||
#include "src/variables/multipart_boundary_whitespace.h"
|
||||
#include "src/variables/multipart_crlf_lf_lines.h"
|
||||
|
|
@ -368,6 +370,8 @@ using namespace modsecurity::operators;
|
|||
VARIABLE_INBOUND_DATA_ERROR "INBOUND_DATA_ERROR"
|
||||
VARIABLE_MATCHED_VAR "MATCHED_VAR"
|
||||
VARIABLE_MATCHED_VAR_NAME "MATCHED_VAR_NAME"
|
||||
VARIABLE_MSC_PCRE_ERROR "MSC_PCRE_ERROR"
|
||||
VARIABLE_MSC_PCRE_LIMITS_EXCEEDED "MSC_PCRE_LIMITS_EXCEEDED"
|
||||
VARIABLE_MULTIPART_BOUNDARY_QUOTED
|
||||
VARIABLE_MULTIPART_BOUNDARY_WHITESPACE
|
||||
VARIABLE_MULTIPART_CRLF_LF_LINES "MULTIPART_CRLF_LF_LINES"
|
||||
|
|
@ -1648,10 +1652,10 @@ expression:
|
|||
YYERROR;
|
||||
*/
|
||||
| CONFIG_DIR_PCRE_MATCH_LIMIT
|
||||
/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended
|
||||
driver.error(@0, "SecPcreMatchLimit is not currently supported. Default PCRE values are being used for now");
|
||||
YYERROR;
|
||||
*/
|
||||
{
|
||||
driver.m_pcreMatchLimit.m_set = true;
|
||||
driver.m_pcreMatchLimit.m_value = atoi($1.c_str());
|
||||
}
|
||||
| CONGIG_DIR_RESPONSE_BODY_MP
|
||||
{
|
||||
std::istringstream buf($1);
|
||||
|
|
@ -2321,6 +2325,14 @@ var:
|
|||
{
|
||||
VARIABLE_CONTAINER($$, new variables::MatchedVarName());
|
||||
}
|
||||
| VARIABLE_MSC_PCRE_ERROR
|
||||
{
|
||||
VARIABLE_CONTAINER($$, new variables::MscPcreError());
|
||||
}
|
||||
| VARIABLE_MSC_PCRE_LIMITS_EXCEEDED
|
||||
{
|
||||
VARIABLE_CONTAINER($$, new variables::MscPcreLimitsExceeded());
|
||||
}
|
||||
| VARIABLE_MULTIPART_BOUNDARY_QUOTED
|
||||
{
|
||||
VARIABLE_CONTAINER($$, new variables::MultipartBoundaryQuoted());
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -186,6 +186,8 @@ VARIABLE_GLOBAL (?i:GLOBAL)
|
|||
VARIABLE_INBOUND_DATA_ERROR (?i:INBOUND_DATA_ERROR)
|
||||
VARIABLE_MATCHED_VAR (?i:MATCHED_VAR)
|
||||
VARIABLE_MATCHED_VAR_NAME (?i:MATCHED_VAR_NAME)
|
||||
VARIABLE_MSC_PCRE_ERROR (?i:MSC_PCRE_ERROR)
|
||||
VARIABLE_MSC_PCRE_LIMITS_EXCEEDED (?i:MSC_PCRE_LIMITS_EXCEEDED)
|
||||
VARIABLE_MULTIPART_BOUNDARY_QUOTED (?i:MULTIPART_BOUNDARY_QUOTED)
|
||||
VARIABLE_MULTIPART_BOUNDARY_WHITESPACE (?i:MULTIPART_BOUNDARY_WHITESPACE)
|
||||
VARIABLE_MULTIPART_CRLF_LF_LINES (?i:MULTIPART_CRLF_LF_LINES)
|
||||
|
|
@ -910,6 +912,8 @@ EQUALS_MINUS (?i:=\-)
|
|||
{VARIABLE_INBOUND_DATA_ERROR} { return p::make_VARIABLE_INBOUND_DATA_ERROR(*driver.loc.back()); }
|
||||
{VARIABLE_MATCHED_VAR_NAME} { return p::make_VARIABLE_MATCHED_VAR_NAME(*driver.loc.back()); }
|
||||
{VARIABLE_MATCHED_VAR} { return p::make_VARIABLE_MATCHED_VAR(*driver.loc.back()); }
|
||||
{VARIABLE_MSC_PCRE_ERROR} { return p::make_VARIABLE_MSC_PCRE_ERROR(*driver.loc.back()); }
|
||||
{VARIABLE_MSC_PCRE_LIMITS_EXCEEDED} { return p::make_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED(*driver.loc.back()); }
|
||||
{VARIABLE_MULTIPART_BOUNDARY_QUOTED} { return p::make_VARIABLE_MULTIPART_BOUNDARY_QUOTED(*driver.loc.back()); }
|
||||
{VARIABLE_MULTIPART_BOUNDARY_WHITESPACE} { return p::make_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE(*driver.loc.back()); }
|
||||
{VARIABLE_MULTIPART_CRLF_LF_LINES} { return p::make_VARIABLE_MULTIPART_CRLF_LF_LINES(*driver.loc.back()); }
|
||||
|
|
@ -1271,9 +1275,9 @@ EQUALS_MINUS (?i:=\-)
|
|||
{CONFIG_INCLUDE}[ \t]+["]{CONFIG_VALUE_PATH}["] {
|
||||
std::string err;
|
||||
const char *tmpStr = yytext + strlen("include");
|
||||
const char *file = tmpStr + strspn( tmpStr, " \t");
|
||||
char *f = strdup(file);
|
||||
std::string fi = modsecurity::utils::find_resource(f, *driver.loc.back()->end.filename, &err);
|
||||
const char *afterWhitespace = tmpStr + strspn( tmpStr, " \t");
|
||||
std::string file(afterWhitespace+1, strlen(afterWhitespace)-2);
|
||||
std::string fi = modsecurity::utils::find_resource(file, *driver.loc.back()->end.filename, &err);
|
||||
if (fi.empty() == true) {
|
||||
BEGIN(INITIAL);
|
||||
driver.error (*driver.loc.back(), "", file + std::string(": Not able to open file. ") + err);
|
||||
|
|
@ -1296,7 +1300,6 @@ EQUALS_MINUS (?i:=\-)
|
|||
}
|
||||
yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));
|
||||
}
|
||||
free(f);
|
||||
}
|
||||
|
||||
{CONFIG_SEC_REMOTE_RULES}[ ][^ ]+[ ][^\n\r ]+ {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// A Bison parser, made by GNU Bison 3.7.6.
|
||||
// A Bison parser, made by GNU Bison 3.8.2.
|
||||
|
||||
// Starting with Bison 3.2, this file is useless: the structure it
|
||||
// used to define is now defined with the parser itself.
|
||||
|
|
|
|||
|
|
@ -935,7 +935,7 @@ int Multipart::process_part_header(std::string *error, int offset) {
|
|||
"Multipart: Added part header \"" + header_name \
|
||||
+ "\" \"" + header_value + "\".");
|
||||
if (len_without_termination > 0) {
|
||||
m_mpp->m_last_header_line.assign(m_buf);
|
||||
m_mpp->m_last_header_line.assign(m_buf, len_without_termination);
|
||||
} else {
|
||||
m_mpp->m_last_header_line.assign("");
|
||||
}
|
||||
|
|
@ -1198,15 +1198,9 @@ int Multipart::multipart_complete(std::string *error) {
|
|||
size_t offset = m_transaction->m_variableOffset + 1;
|
||||
|
||||
if (m->m_type == MULTIPART_FILE) {
|
||||
std::string tmp_name;
|
||||
std::string name;
|
||||
if (m->m_tmp_file && !m->m_tmp_file->getFilename().empty()) {
|
||||
tmp_name.assign(m->m_tmp_file->getFilename());
|
||||
m_transaction->m_variableFilesTmpNames.set(m->m_tmp_file->getFilename(),
|
||||
m->m_tmp_file->getFilename(), m->m_filenameOffset);
|
||||
}
|
||||
if (!m->m_filename.empty()) {
|
||||
name.assign(m->m_filename);
|
||||
if (m->m_tmp_file && !m->m_tmp_file->getFilename().empty()) {
|
||||
m_transaction->m_variableFilesTmpNames.set(m->m_tmp_file->getFilename(),
|
||||
m->m_tmp_file->getFilename(), m->m_filenameOffset);
|
||||
}
|
||||
|
||||
m_transaction->m_variableFiles.set(m->m_name,
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ void RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction *
|
|||
}
|
||||
}
|
||||
|
||||
if (m_containsMultiMatchAction && !m_isChained) {
|
||||
if (m_containsMultiMatchAction && m_chainedRuleParent == nullptr) {
|
||||
if (m_severity) {
|
||||
m_severity->evaluate(this, trans, ruleMessage);
|
||||
}
|
||||
|
|
@ -229,6 +229,9 @@ void RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction *
|
|||
if (m_msg) {
|
||||
m_msg->evaluate(this, trans, ruleMessage);
|
||||
}
|
||||
for (actions::Tag *a : m_actionsTag) {
|
||||
a->evaluate(this, trans, ruleMessage);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,8 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData)
|
|||
+ std::to_string(modsecurity::utils::generate_transaction_unique_id())));
|
||||
|
||||
m_variableUrlEncodedError.set("0", 0);
|
||||
m_variableMscPcreError.set("0", 0);
|
||||
m_variableMscPcreLimitsExceeded.set("0", 0);
|
||||
|
||||
ms_dbg(4, "Initializing transaction");
|
||||
|
||||
|
|
@ -238,6 +240,8 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, char *id, void *logCb
|
|||
TransactionAnchoredVariables(this) {
|
||||
|
||||
m_variableUrlEncodedError.set("0", 0);
|
||||
m_variableMscPcreError.set("0", 0);
|
||||
m_variableMscPcreLimitsExceeded.set("0", 0);
|
||||
|
||||
ms_dbg(4, "Initializing transaction");
|
||||
|
||||
|
|
|
|||
|
|
@ -258,11 +258,13 @@ int InsertNetmask(TreeNode *node, TreeNode *parent, TreeNode *new_node,
|
|||
}
|
||||
|
||||
node->count++;
|
||||
|
||||
node->netmasks = reinterpret_cast<unsigned char *>(malloc(node->count * sizeof(unsigned char)));
|
||||
if(node->netmasks == NULL) {
|
||||
return 0;
|
||||
}
|
||||
memset(node->netmasks, 0, (node->count * sizeof(unsigned char)));
|
||||
|
||||
if(node->netmasks == NULL)
|
||||
return 0;
|
||||
if ((node->count-1) == 0) {
|
||||
node->netmasks[0] = netmask;
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -25,12 +25,38 @@
|
|||
|
||||
#ifndef WITH_PCRE2
|
||||
#if PCRE_HAVE_JIT
|
||||
#define pcre_study_opt PCRE_STUDY_JIT_COMPILE
|
||||
// NOTE: Add PCRE_STUDY_EXTRA_NEEDED so studying always yields a pcre_extra strucure
|
||||
// and we can selectively override match limits using a copy of that structure at runtime.
|
||||
#define pcre_study_opt PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_EXTRA_NEEDED
|
||||
#else
|
||||
#define pcre_study_opt 0
|
||||
// NOTE: Add PCRE_STUDY_EXTRA_NEEDED so studying always yields a pcre_extra strucure
|
||||
// and we can selectively override match limits using a copy of that structure at runtime.
|
||||
#define pcre_study_opt PCRE_STUDY_EXTRA_NEEDED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PCRE2
|
||||
class Pcre2MatchContextPtr {
|
||||
public:
|
||||
Pcre2MatchContextPtr()
|
||||
: m_match_context(pcre2_match_context_create(NULL)) {}
|
||||
|
||||
Pcre2MatchContextPtr(const Pcre2MatchContextPtr&) = delete;
|
||||
Pcre2MatchContextPtr& operator=(const Pcre2MatchContextPtr&) = delete;
|
||||
|
||||
~Pcre2MatchContextPtr() {
|
||||
pcre2_match_context_free(m_match_context);
|
||||
}
|
||||
|
||||
operator pcre2_match_context*() const {
|
||||
return m_match_context;
|
||||
}
|
||||
|
||||
private:
|
||||
pcre2_match_context *m_match_context;
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace modsecurity {
|
||||
namespace Utils {
|
||||
|
||||
|
|
@ -163,24 +189,39 @@ std::list<SMatch> Regex::searchAll(const std::string& s) const {
|
|||
return retList;
|
||||
}
|
||||
|
||||
bool Regex::searchOneMatch(const std::string& s, std::vector<SMatchCapture>& captures) const {
|
||||
RegexResult Regex::searchOneMatch(const std::string& s, std::vector<SMatchCapture>& captures, unsigned long match_limit) const {
|
||||
#ifdef WITH_PCRE2
|
||||
Pcre2MatchContextPtr match_context;
|
||||
if (match_limit > 0) {
|
||||
// TODO: What if setting the match limit fails?
|
||||
pcre2_set_match_limit(match_context, match_limit);
|
||||
}
|
||||
|
||||
PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str());
|
||||
pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL);
|
||||
int rc = 0;
|
||||
if (m_pcje == 0) {
|
||||
rc = pcre2_jit_match(m_pc, pcre2_s, s.length(), 0, 0, match_data, NULL);
|
||||
rc = pcre2_jit_match(m_pc, pcre2_s, s.length(), 0, 0, match_data, match_context);
|
||||
}
|
||||
|
||||
if (m_pcje != 0 || rc == PCRE2_ERROR_JIT_STACKLIMIT) {
|
||||
rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, PCRE2_NO_JIT, match_data, NULL);
|
||||
rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, PCRE2_NO_JIT, match_data, match_context);
|
||||
}
|
||||
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
|
||||
#else
|
||||
const char *subject = s.c_str();
|
||||
int ovector[OVECCOUNT];
|
||||
pcre_extra local_pce;
|
||||
pcre_extra *pce = m_pce;
|
||||
|
||||
int rc = pcre_exec(m_pc, m_pce, subject, s.size(), 0, 0, ovector, OVECCOUNT);
|
||||
if (m_pce != NULL && match_limit > 0) {
|
||||
local_pce = *m_pce;
|
||||
local_pce.match_limit = match_limit;
|
||||
local_pce.flags |= PCRE_EXTRA_MATCH_LIMIT;
|
||||
pce = &local_pce;
|
||||
}
|
||||
|
||||
int rc = pcre_exec(m_pc, pce, subject, s.size(), 0, 0, ovector, OVECCOUNT);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < rc; i++) {
|
||||
|
|
@ -197,12 +238,18 @@ bool Regex::searchOneMatch(const std::string& s, std::vector<SMatchCapture>& cap
|
|||
#ifdef WITH_PCRE2
|
||||
pcre2_match_data_free(match_data);
|
||||
#endif
|
||||
return (rc > 0);
|
||||
return to_regex_result(rc);
|
||||
}
|
||||
|
||||
bool Regex::searchGlobal(const std::string& s, std::vector<SMatchCapture>& captures) const {
|
||||
RegexResult Regex::searchGlobal(const std::string& s, std::vector<SMatchCapture>& captures, unsigned long match_limit) const {
|
||||
bool prev_match_zero_length = false;
|
||||
#ifdef WITH_PCRE2
|
||||
Pcre2MatchContextPtr match_context;
|
||||
if (match_limit > 0) {
|
||||
// TODO: What if setting the match limit fails?
|
||||
pcre2_set_match_limit(match_context, match_limit);
|
||||
}
|
||||
|
||||
PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str());
|
||||
PCRE2_SIZE startOffset = 0;
|
||||
|
||||
|
|
@ -213,11 +260,21 @@ bool Regex::searchGlobal(const std::string& s, std::vector<SMatchCapture>& captu
|
|||
pcre2_options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
|
||||
}
|
||||
int rc = pcre2_match(m_pc, pcre2_s, s.length(),
|
||||
startOffset, pcre2_options, match_data, NULL);
|
||||
startOffset, pcre2_options, match_data, match_context);
|
||||
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
|
||||
|
||||
#else
|
||||
const char *subject = s.c_str();
|
||||
pcre_extra local_pce;
|
||||
pcre_extra *pce = m_pce;
|
||||
|
||||
if (m_pce != NULL && match_limit > 0) {
|
||||
local_pce = *m_pce;
|
||||
local_pce.match_limit = match_limit;
|
||||
local_pce.flags |= PCRE_EXTRA_MATCH_LIMIT;
|
||||
pce = &local_pce;
|
||||
}
|
||||
|
||||
int startOffset = 0;
|
||||
|
||||
while (startOffset <= s.length()) {
|
||||
|
|
@ -226,7 +283,12 @@ bool Regex::searchGlobal(const std::string& s, std::vector<SMatchCapture>& captu
|
|||
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);
|
||||
int rc = pcre_exec(m_pc, pce, subject, s.length(), startOffset, pcre_options, ovector, OVECCOUNT);
|
||||
|
||||
RegexResult regex_result = to_regex_result(rc);
|
||||
if (regex_result != RegexResult::Ok) {
|
||||
return regex_result;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (rc > 0) {
|
||||
|
|
@ -278,7 +340,7 @@ bool Regex::searchGlobal(const std::string& s, std::vector<SMatchCapture>& captu
|
|||
#ifdef WITH_PCRE2
|
||||
pcre2_match_data_free(match_data);
|
||||
#endif
|
||||
return (captures.size() > 0);
|
||||
return RegexResult::Ok;
|
||||
}
|
||||
|
||||
int Regex::search(const std::string& s, SMatch *match) const {
|
||||
|
|
@ -340,5 +402,30 @@ int Regex::search(const std::string& s) const {
|
|||
#endif
|
||||
}
|
||||
|
||||
RegexResult Regex::to_regex_result(int pcre_exec_result) const {
|
||||
if (
|
||||
pcre_exec_result > 0 ||
|
||||
#ifdef WITH_PCRE2
|
||||
pcre_exec_result == PCRE2_ERROR_NOMATCH
|
||||
#else
|
||||
pcre_exec_result == PCRE_ERROR_NOMATCH
|
||||
#endif
|
||||
) {
|
||||
return RegexResult::Ok;
|
||||
} else if(
|
||||
#ifdef WITH_PCRE2
|
||||
pcre_exec_result == PCRE2_ERROR_MATCHLIMIT
|
||||
#else
|
||||
pcre_exec_result == PCRE_ERROR_MATCHLIMIT
|
||||
#endif
|
||||
) {
|
||||
return RegexResult::ErrorMatchLimit;
|
||||
} else {
|
||||
// Note that this can include the case where the PCRE result was zero.
|
||||
// Zero is returned if the offset vector is not large enough and can be considered an error.
|
||||
return RegexResult::ErrorOther;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace modsecurity
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ namespace Utils {
|
|||
|
||||
#define OVECCOUNT 900
|
||||
|
||||
enum class RegexResult {
|
||||
Ok,
|
||||
ErrorMatchLimit,
|
||||
ErrorOther,
|
||||
};
|
||||
|
||||
class SMatch {
|
||||
public:
|
||||
SMatch() :
|
||||
|
|
@ -76,13 +82,15 @@ class Regex {
|
|||
return (m_pc == NULL);
|
||||
}
|
||||
std::list<SMatch> searchAll(const std::string& s) const;
|
||||
bool searchOneMatch(const std::string& s, std::vector<SMatchCapture>& captures) const;
|
||||
bool searchGlobal(const std::string& s, std::vector<SMatchCapture>& captures) const;
|
||||
RegexResult searchOneMatch(const std::string& s, std::vector<SMatchCapture>& captures, unsigned long match_limit = 0) const;
|
||||
RegexResult searchGlobal(const std::string& s, std::vector<SMatchCapture>& captures, unsigned long match_limit = 0) const;
|
||||
int search(const std::string &s, SMatch *match) const;
|
||||
int search(const std::string &s) const;
|
||||
|
||||
const std::string pattern;
|
||||
private:
|
||||
RegexResult to_regex_result(int pcre_exec_result) const;
|
||||
|
||||
#if WITH_PCRE2
|
||||
pcre2_code *m_pc;
|
||||
int m_pcje;
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ void chomp(std::string *str) {
|
|||
}
|
||||
|
||||
|
||||
unsigned char x2c(unsigned char *what) {
|
||||
unsigned char x2c(const unsigned char *what) {
|
||||
unsigned char digit;
|
||||
|
||||
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
|
||||
|
|
@ -239,7 +239,7 @@ unsigned char x2c(unsigned char *what) {
|
|||
/**
|
||||
* Converts a single hexadecimal digit into a decimal value.
|
||||
*/
|
||||
unsigned char xsingle2c(unsigned char *what) {
|
||||
unsigned char xsingle2c(const unsigned char *what) {
|
||||
unsigned char digit;
|
||||
|
||||
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ void replaceAll(std::string *str, const std::string& from,
|
|||
std::string removeWhiteSpacesIfNeeded(std::string a);
|
||||
std::string parserSanitizer(std::string a);
|
||||
|
||||
unsigned char x2c(unsigned char *what);
|
||||
unsigned char xsingle2c(unsigned char *what);
|
||||
unsigned char x2c(const unsigned char *what);
|
||||
unsigned char xsingle2c(const unsigned char *what);
|
||||
unsigned char *c2x(unsigned what, unsigned char *where);
|
||||
|
||||
} // namespace string
|
||||
|
|
|
|||
|
|
@ -106,8 +106,8 @@ class Global_DynamicElement : public Variable {
|
|||
t->m_rules->m_secWebAppId.m_value);
|
||||
}
|
||||
|
||||
static void storeOrUpdateFirst(Transaction *t, std::string var,
|
||||
std::string value) {
|
||||
static void storeOrUpdateFirst(Transaction *t, const std::string &var,
|
||||
const std::string &value) {
|
||||
t->m_collections.m_global_collection->storeOrUpdateFirst(
|
||||
var, t->m_collections.m_global_collection_key,
|
||||
t->m_rules->m_secWebAppId.m_value,
|
||||
|
|
|
|||
39
src/deps/src/modsecurity/src/variables/msc_pcre_error.h
Normal file
39
src/deps/src/modsecurity/src/variables/msc_pcre_error.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 - 2022 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 <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
|
||||
#ifndef SRC_VARIABLES_MSC_PCRE_ERROR_H_
|
||||
#define SRC_VARIABLES_MSC_PCRE_ERROR_H_
|
||||
|
||||
#include "src/variables/variable.h"
|
||||
|
||||
namespace modsecurity {
|
||||
|
||||
class Transaction;
|
||||
namespace variables {
|
||||
|
||||
|
||||
DEFINE_VARIABLE(MscPcreError, MSC_PCRE_ERROR, m_variableMscPcreError)
|
||||
|
||||
|
||||
} // namespace variables
|
||||
} // namespace modsecurity
|
||||
|
||||
#endif // SRC_VARIABLES_MSC_PCRE_ERROR_H_
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 - 2022 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 <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
|
||||
#ifndef SRC_VARIABLES_MSC_PCRE_LIMITS_EXCEEDED_H_
|
||||
#define SRC_VARIABLES_MSC_PCRE_LIMITS_EXCEEDED_H_
|
||||
|
||||
#include "src/variables/variable.h"
|
||||
|
||||
namespace modsecurity {
|
||||
|
||||
class Transaction;
|
||||
namespace variables {
|
||||
|
||||
|
||||
DEFINE_VARIABLE(MscPcreLimitsExceeded, MSC_PCRE_LIMITS_EXCEEDED, m_variableMscPcreLimitsExceeded)
|
||||
|
||||
|
||||
} // namespace variables
|
||||
} // namespace modsecurity
|
||||
|
||||
#endif // SRC_VARIABLES_MSC_PCRE_LIMITS_EXCEEDED_H_
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2015 - 2023 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
|
||||
|
|
@ -179,163 +179,201 @@ class VariableMonkeyResolution {
|
|||
static void stringMatchResolveMulti(Transaction *t,
|
||||
const std::string &variable,
|
||||
std::vector<const VariableValue *> *l) {
|
||||
size_t collection = variable.find(".");
|
||||
if (collection == std::string::npos) {
|
||||
collection = variable.find(":");
|
||||
size_t collection_delimiter_offset = variable.find(".");
|
||||
if (collection_delimiter_offset == std::string::npos) {
|
||||
collection_delimiter_offset = variable.find(":");
|
||||
}
|
||||
if (collection == std::string::npos) {
|
||||
if (comp(variable, "RESPONSE_CONTENT_TYPE")) {
|
||||
t->m_variableResponseContentType.evaluate(l);
|
||||
} else if (comp(variable, "ARGS_COMBINED_SIZE")) {
|
||||
t->m_variableARGScombinedSize.evaluate(l);
|
||||
} else if (comp(variable, "AUTH_TYPE")) {
|
||||
t->m_variableAuthType.evaluate(l);
|
||||
} else if (comp(variable, "FILES_COMBINED_SIZE")) {
|
||||
t->m_variableFilesCombinedSize.evaluate(l);
|
||||
} else if (comp(variable, "FULL_REQUEST")) {
|
||||
t->m_variableFullRequest.evaluate(l);
|
||||
} else if (comp(variable, "FULL_REQUEST_LENGTH")) {
|
||||
t->m_variableFullRequestLength.evaluate(l);
|
||||
} else if (comp(variable, "INBOUND_DATA_ERROR")) {
|
||||
t->m_variableInboundDataError.evaluate(l);
|
||||
} else if (comp(variable, "MATCHED_VAR")) {
|
||||
t->m_variableMatchedVar.evaluate(l);
|
||||
} else if (comp(variable, "MATCHED_VAR_NAME")) {
|
||||
t->m_variableMatchedVarName.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_CRLF_LF_LINES")) {
|
||||
t->m_variableMultipartCrlfLFLines.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_DATA_AFTER")) {
|
||||
t->m_variableMultipartDataAfter.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_FILE_LIMIT_EXCEEDED")) {
|
||||
t->m_variableMultipartFileLimitExceeded.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_STRICT_ERROR")) {
|
||||
t->m_variableMultipartStrictError.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_HEADER_FOLDING")) {
|
||||
t->m_variableMultipartHeaderFolding.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_INVALID_QUOTING")) {
|
||||
t->m_variableMultipartInvalidQuoting.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_INVALID_HEADER_FOLDING")) {
|
||||
t->m_variableMultipartInvalidHeaderFolding.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_UNMATCHED_BOUNDARY")) {
|
||||
t->m_variableMultipartUnmatchedBoundary.evaluate(l);
|
||||
} else if (comp(variable, "OUTBOUND_DATA_ERROR")) {
|
||||
t->m_variableOutboundDataError.evaluate(l);
|
||||
} else if (comp(variable, "PATH_INFO")) {
|
||||
t->m_variablePathInfo.evaluate(l);
|
||||
} else if (comp(variable, "QUERY_STRING")) {
|
||||
t->m_variableQueryString.evaluate(l);
|
||||
} else if (comp(variable, "REMOTE_ADDR")) {
|
||||
t->m_variableRemoteAddr.evaluate(l);
|
||||
} else if (comp(variable, "REMOTE_HOST")) {
|
||||
t->m_variableRemoteHost.evaluate(l);
|
||||
} else if (comp(variable, "REMOTE_PORT")) {
|
||||
t->m_variableRemotePort.evaluate(l);
|
||||
} else if (comp(variable, "REQBODY_ERROR")) {
|
||||
t->m_variableReqbodyError.evaluate(l);
|
||||
} else if (comp(variable, "REQBODY_ERROR_MSG")) {
|
||||
t->m_variableReqbodyErrorMsg.evaluate(l);
|
||||
} else if (comp(variable, "REQBODY_PROCESSOR_ERROR_MSG")) {
|
||||
t->m_variableReqbodyProcessorErrorMsg.evaluate(l);
|
||||
} else if (comp(variable, "REQBODY_PROCESSOR_ERROR")) {
|
||||
t->m_variableReqbodyProcessorError.evaluate(l);
|
||||
} else if (comp(variable, "REQBODY_PROCESSOR")) {
|
||||
t->m_variableReqbodyProcessor.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_BASENAME")) {
|
||||
t->m_variableRequestBasename.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_BODY")) {
|
||||
t->m_variableRequestBody.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_BODY_LENGTH")) {
|
||||
t->m_variableRequestBodyLength.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_FILENAME")) {
|
||||
t->m_variableRequestFilename.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_LINE")) {
|
||||
t->m_variableRequestLine.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_METHOD")) {
|
||||
t->m_variableRequestMethod.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_PROTOCOL")) {
|
||||
t->m_variableRequestProtocol.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_URI")) {
|
||||
t->m_variableRequestURI.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_URI_RAW")) {
|
||||
t->m_variableRequestURIRaw.evaluate(l);
|
||||
} else if (comp(variable, "RESOURCE")) {
|
||||
t->m_variableResource.evaluate(l);
|
||||
} else if (comp(variable, "RESPONSE_BODY")) {
|
||||
t->m_variableResponseBody.evaluate(l);
|
||||
} else if (comp(variable, "RESPONSE_CONTENT_LENGTH")) {
|
||||
t->m_variableResponseContentLength.evaluate(l);
|
||||
} else if (comp(variable, "RESPONSE_PROTOCOL")) {
|
||||
t->m_variableResponseProtocol.evaluate(l);
|
||||
} else if (comp(variable, "RESPONSE_STATUS")) {
|
||||
t->m_variableResponseStatus.evaluate(l);
|
||||
} else if (comp(variable, "SERVER_ADDR")) {
|
||||
t->m_variableServerAddr.evaluate(l);
|
||||
} else if (comp(variable, "SERVER_NAME")) {
|
||||
t->m_variableServerName.evaluate(l);
|
||||
} else if (comp(variable, "SERVER_PORT")) {
|
||||
t->m_variableServerPort.evaluate(l);
|
||||
} else if (comp(variable, "SESSIONID")) {
|
||||
t->m_variableSessionID.evaluate(l);
|
||||
} else if (comp(variable, "UNIQUE_ID")) {
|
||||
t->m_variableUniqueID.evaluate(l);
|
||||
} else if (comp(variable, "URLENCODED_ERROR")) {
|
||||
t->m_variableUrlEncodedError.evaluate(l);
|
||||
} else if (comp(variable, "USERID")) {
|
||||
t->m_variableUserID.evaluate(l);
|
||||
} else {
|
||||
throw std::invalid_argument("Variable not found.");
|
||||
}
|
||||
std::string col; // collection name excluding individual variable specification
|
||||
std::string var; // variable within the collection
|
||||
if (collection_delimiter_offset == std::string::npos) {
|
||||
col = variable;
|
||||
} else {
|
||||
std::string col = std::string(variable, 0, collection);
|
||||
std::string var = std::string(variable, collection + 1,
|
||||
variable.length() - (collection + 1));
|
||||
if (comp(col, "ARGS")) {
|
||||
t->m_variableArgs.resolve(var, l);
|
||||
} else if (comp(variable, "ARGS_NAMES")) {
|
||||
t->m_variableArgsNames.resolve(var, l);
|
||||
} else if (comp(variable, "ARGS_GET_NAMES")) {
|
||||
t->m_variableArgsGetNames.resolve(var, l);
|
||||
} else if (comp(variable, "ARGS_POST_NAMES")) {
|
||||
t->m_variableArgsPostNames.resolve(var, l);
|
||||
} else if (comp(col, "ARGS_GET")) {
|
||||
t->m_variableArgsGet.resolve(var, l);
|
||||
} else if (comp(col, "ARGS_POST")) {
|
||||
t->m_variableArgsPost.resolve(var, l);
|
||||
} else if (comp(col, "FILES_SIZES")) {
|
||||
t->m_variableFilesSizes.resolve(var, l);
|
||||
} else if (comp(col, "FILES_NAMES")) {
|
||||
t->m_variableFilesNames.resolve(var, l);
|
||||
} else if (comp(col, "FILES_TMP_CONTENT")) {
|
||||
t->m_variableFilesTmpContent.resolve(var, l);
|
||||
} else if (comp(col, "MULTIPART_FILENAME")) {
|
||||
t->m_variableMultipartFileName.resolve(var, l);
|
||||
} else if (comp(col, "MULTIPART_NAME")) {
|
||||
t->m_variableMultipartName.resolve(var, l);
|
||||
} else if (comp(col, "MATCHED_VARS_NAMES")) {
|
||||
t->m_variableMatchedVarsNames.resolve(var, l);
|
||||
} else if (comp(col, "MATCHED_VARS")) {
|
||||
t->m_variableMatchedVars.resolve(var, l);
|
||||
} else if (comp(col, "FILES")) {
|
||||
t->m_variableFiles.resolve(var, l);
|
||||
} else if (comp(col, "REQUEST_COOKIES")) {
|
||||
t->m_variableRequestCookies.resolve(var, l);
|
||||
} else if (comp(col, "REQUEST_HEADERS")) {
|
||||
t->m_variableRequestHeaders.resolve(var, l);
|
||||
} else if (comp(variable, "REQUEST_HEADERS_NAMES")) {
|
||||
t->m_variableRequestHeadersNames.resolve(var, l);
|
||||
} else if (comp(col, "RESPONSE_HEADERS")) {
|
||||
t->m_variableResponseHeaders.resolve(var, l);
|
||||
} else if (comp(variable, "RESPONSE_HEADERS_NAMES")) {
|
||||
t->m_variableResponseHeadersNames.resolve(var, l);
|
||||
} else if (comp(col, "GEO")) {
|
||||
t->m_variableGeo.resolve(var, l);
|
||||
} else if (comp(col, "REQUEST_COOKIES_NAMES")) {
|
||||
t->m_variableRequestCookiesNames.resolve(var, l);
|
||||
} else if (comp(col, "FILES_TMPNAMES")) {
|
||||
t->m_variableFilesTmpNames.resolve(var, l);
|
||||
col = std::string(variable, 0, collection_delimiter_offset);
|
||||
var = std::string(variable, collection_delimiter_offset + 1,
|
||||
variable.length() - (collection_delimiter_offset + 1));
|
||||
}
|
||||
|
||||
// First check if the request is for a collection of type AnchoredSetVariable
|
||||
AnchoredSetVariable* anchoredSetVariable = NULL;
|
||||
if (comp(col, "ARGS")) {
|
||||
anchoredSetVariable = &t->m_variableArgs;
|
||||
} else if (comp(col, "ARGS_GET")) {
|
||||
anchoredSetVariable = &t->m_variableArgsGet;
|
||||
} else if (comp(col, "ARGS_POST")) {
|
||||
anchoredSetVariable = &t->m_variableArgsPost;
|
||||
} else if (comp(col, "FILES_SIZES")) {
|
||||
anchoredSetVariable = &t->m_variableFilesSizes;
|
||||
} else if (comp(col, "FILES_NAMES")) {
|
||||
anchoredSetVariable = &t->m_variableFilesNames;
|
||||
} else if (comp(col, "FILES_TMP_CONTENT")) {
|
||||
anchoredSetVariable = &t->m_variableFilesTmpContent;
|
||||
} else if (comp(col, "MULTIPART_FILENAME")) {
|
||||
anchoredSetVariable = &t->m_variableMultipartFileName;
|
||||
} else if (comp(col, "MULTIPART_NAME")) {
|
||||
anchoredSetVariable = &t->m_variableMultipartName;
|
||||
} else if (comp(col, "MATCHED_VARS_NAMES")) {
|
||||
anchoredSetVariable = &t->m_variableMatchedVarsNames;
|
||||
} else if (comp(col, "MATCHED_VARS")) {
|
||||
anchoredSetVariable = &t->m_variableMatchedVars;
|
||||
} else if (comp(col, "FILES")) {
|
||||
anchoredSetVariable = &t->m_variableFiles;
|
||||
} else if (comp(col, "REQUEST_COOKIES")) {
|
||||
anchoredSetVariable = &t->m_variableRequestCookies;
|
||||
} else if (comp(col, "REQUEST_HEADERS")) {
|
||||
anchoredSetVariable = &t->m_variableRequestHeaders;
|
||||
} else if (comp(variable, "REQUEST_HEADERS_NAMES")) {
|
||||
anchoredSetVariable = &t->m_variableRequestHeadersNames;
|
||||
} else if (comp(col, "RESPONSE_HEADERS")) {
|
||||
anchoredSetVariable = &t->m_variableResponseHeaders;
|
||||
} else if (comp(variable, "RESPONSE_HEADERS_NAMES")) {
|
||||
anchoredSetVariable = &t->m_variableResponseHeadersNames;
|
||||
} else if (comp(col, "GEO")) {
|
||||
anchoredSetVariable = &t->m_variableGeo;
|
||||
} else if (comp(col, "REQUEST_COOKIES_NAMES")) {
|
||||
anchoredSetVariable = &t->m_variableRequestCookiesNames;
|
||||
} else if (comp(col, "MULTIPART_PART_HEADERS")) {
|
||||
anchoredSetVariable = &t->m_variableMultipartPartHeaders;
|
||||
} else if (comp(col, "FILES_TMPNAMES")) {
|
||||
anchoredSetVariable = &t->m_variableFilesTmpNames;
|
||||
}
|
||||
if (anchoredSetVariable != NULL) {
|
||||
if (collection_delimiter_offset == std::string::npos) {
|
||||
anchoredSetVariable->resolve(l);
|
||||
} else {
|
||||
throw std::invalid_argument("Variable not found.");
|
||||
anchoredSetVariable->resolve(var, l);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Next check for collection of type AnchoredSetVariableTranslationProxy
|
||||
AnchoredSetVariableTranslationProxy* anchoredSetVariableTranslationProxy = NULL;
|
||||
if (comp(col, "ARGS_NAMES")) {
|
||||
anchoredSetVariableTranslationProxy = &t->m_variableArgsNames;
|
||||
} else if (comp(col, "ARGS_GET_NAMES")) {
|
||||
anchoredSetVariableTranslationProxy = &t->m_variableArgsGetNames;
|
||||
} else if (comp(col, "ARGS_POST_NAMES")) {
|
||||
anchoredSetVariableTranslationProxy = &t->m_variableArgsPostNames;
|
||||
}
|
||||
if (anchoredSetVariableTranslationProxy != NULL) {
|
||||
if (collection_delimiter_offset == std::string::npos) {
|
||||
anchoredSetVariableTranslationProxy->resolve(l);
|
||||
} else {
|
||||
anchoredSetVariableTranslationProxy->resolve(var, l);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// It could still be a non-collection variable, but in that case
|
||||
// there should not be a request for a variable-within-a-collection
|
||||
if (collection_delimiter_offset != std::string::npos) {
|
||||
throw std::invalid_argument("Variable not found.");
|
||||
}
|
||||
|
||||
if (comp(variable, "RESPONSE_CONTENT_TYPE")) {
|
||||
t->m_variableResponseContentType.evaluate(l);
|
||||
} else if (comp(variable, "ARGS_COMBINED_SIZE")) {
|
||||
t->m_variableARGScombinedSize.evaluate(l);
|
||||
} else if (comp(variable, "AUTH_TYPE")) {
|
||||
t->m_variableAuthType.evaluate(l);
|
||||
} else if (comp(variable, "FILES_COMBINED_SIZE")) {
|
||||
t->m_variableFilesCombinedSize.evaluate(l);
|
||||
} else if (comp(variable, "FULL_REQUEST")) {
|
||||
t->m_variableFullRequest.evaluate(l);
|
||||
} else if (comp(variable, "FULL_REQUEST_LENGTH")) {
|
||||
t->m_variableFullRequestLength.evaluate(l);
|
||||
} else if (comp(variable, "INBOUND_DATA_ERROR")) {
|
||||
t->m_variableInboundDataError.evaluate(l);
|
||||
} else if (comp(variable, "MATCHED_VAR")) {
|
||||
t->m_variableMatchedVar.evaluate(l);
|
||||
} else if (comp(variable, "MATCHED_VAR_NAME")) {
|
||||
t->m_variableMatchedVarName.evaluate(l);
|
||||
} else if (comp(variable, "MSC_PCRE_ERROR")) {
|
||||
t->m_variableMscPcreError.evaluate(l);
|
||||
} else if (comp(variable, "MSC_PCRE_LIMITS_EXCEEDED")) {
|
||||
t->m_variableMscPcreLimitsExceeded.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_CRLF_LF_LINES")) {
|
||||
t->m_variableMultipartCrlfLFLines.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_DATA_AFTER")) {
|
||||
t->m_variableMultipartDataAfter.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_FILE_LIMIT_EXCEEDED")) {
|
||||
t->m_variableMultipartFileLimitExceeded.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_STRICT_ERROR")) {
|
||||
t->m_variableMultipartStrictError.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_HEADER_FOLDING")) {
|
||||
t->m_variableMultipartHeaderFolding.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_INVALID_QUOTING")) {
|
||||
t->m_variableMultipartInvalidQuoting.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_INVALID_HEADER_FOLDING")) {
|
||||
t->m_variableMultipartInvalidHeaderFolding.evaluate(l);
|
||||
} else if (comp(variable, "MULTIPART_UNMATCHED_BOUNDARY")) {
|
||||
t->m_variableMultipartUnmatchedBoundary.evaluate(l);
|
||||
} else if (comp(variable, "OUTBOUND_DATA_ERROR")) {
|
||||
t->m_variableOutboundDataError.evaluate(l);
|
||||
} else if (comp(variable, "PATH_INFO")) {
|
||||
t->m_variablePathInfo.evaluate(l);
|
||||
} else if (comp(variable, "QUERY_STRING")) {
|
||||
t->m_variableQueryString.evaluate(l);
|
||||
} else if (comp(variable, "REMOTE_ADDR")) {
|
||||
t->m_variableRemoteAddr.evaluate(l);
|
||||
} else if (comp(variable, "REMOTE_HOST")) {
|
||||
t->m_variableRemoteHost.evaluate(l);
|
||||
} else if (comp(variable, "REMOTE_PORT")) {
|
||||
t->m_variableRemotePort.evaluate(l);
|
||||
} else if (comp(variable, "REQBODY_ERROR")) {
|
||||
t->m_variableReqbodyError.evaluate(l);
|
||||
} else if (comp(variable, "REQBODY_ERROR_MSG")) {
|
||||
t->m_variableReqbodyErrorMsg.evaluate(l);
|
||||
} else if (comp(variable, "REQBODY_PROCESSOR_ERROR_MSG")) {
|
||||
t->m_variableReqbodyProcessorErrorMsg.evaluate(l);
|
||||
} else if (comp(variable, "REQBODY_PROCESSOR_ERROR")) {
|
||||
t->m_variableReqbodyProcessorError.evaluate(l);
|
||||
} else if (comp(variable, "REQBODY_PROCESSOR")) {
|
||||
t->m_variableReqbodyProcessor.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_BASENAME")) {
|
||||
t->m_variableRequestBasename.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_BODY")) {
|
||||
t->m_variableRequestBody.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_BODY_LENGTH")) {
|
||||
t->m_variableRequestBodyLength.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_FILENAME")) {
|
||||
t->m_variableRequestFilename.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_LINE")) {
|
||||
t->m_variableRequestLine.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_METHOD")) {
|
||||
t->m_variableRequestMethod.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_PROTOCOL")) {
|
||||
t->m_variableRequestProtocol.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_URI")) {
|
||||
t->m_variableRequestURI.evaluate(l);
|
||||
} else if (comp(variable, "REQUEST_URI_RAW")) {
|
||||
t->m_variableRequestURIRaw.evaluate(l);
|
||||
} else if (comp(variable, "RESOURCE")) {
|
||||
t->m_variableResource.evaluate(l);
|
||||
} else if (comp(variable, "RESPONSE_BODY")) {
|
||||
t->m_variableResponseBody.evaluate(l);
|
||||
} else if (comp(variable, "RESPONSE_CONTENT_LENGTH")) {
|
||||
t->m_variableResponseContentLength.evaluate(l);
|
||||
} else if (comp(variable, "RESPONSE_PROTOCOL")) {
|
||||
t->m_variableResponseProtocol.evaluate(l);
|
||||
} else if (comp(variable, "RESPONSE_STATUS")) {
|
||||
t->m_variableResponseStatus.evaluate(l);
|
||||
} else if (comp(variable, "SERVER_ADDR")) {
|
||||
t->m_variableServerAddr.evaluate(l);
|
||||
} else if (comp(variable, "SERVER_NAME")) {
|
||||
t->m_variableServerName.evaluate(l);
|
||||
} else if (comp(variable, "SERVER_PORT")) {
|
||||
t->m_variableServerPort.evaluate(l);
|
||||
} else if (comp(variable, "SESSIONID")) {
|
||||
t->m_variableSessionID.evaluate(l);
|
||||
} else if (comp(variable, "UNIQUE_ID")) {
|
||||
t->m_variableUniqueID.evaluate(l);
|
||||
} else if (comp(variable, "URLENCODED_ERROR")) {
|
||||
t->m_variableUrlEncodedError.evaluate(l);
|
||||
} else if (comp(variable, "USERID")) {
|
||||
t->m_variableUserID.evaluate(l);
|
||||
} else {
|
||||
throw std::invalid_argument("Variable not found.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -365,6 +403,10 @@ class VariableMonkeyResolution {
|
|||
vv = t->m_variableMatchedVar.resolveFirst();
|
||||
} else if (comp(variable, "MATCHED_VAR_NAME")) {
|
||||
vv = t->m_variableMatchedVarName.resolveFirst();
|
||||
} else if (comp(variable, "MSC_PCRE_ERROR")) {
|
||||
vv = t->m_variableMscPcreError.resolveFirst();
|
||||
} else if (comp(variable, "MSC_PCRE_LIMITS_EXCEEDED")) {
|
||||
vv = t->m_variableMscPcreLimitsExceeded.resolveFirst();
|
||||
} else if (comp(variable, "MULTIPART_CRLF_LF_LINES")) {
|
||||
vv = t->m_variableMultipartCrlfLFLines.resolveFirst();
|
||||
} else if (comp(variable, "MULTIPART_DATA_AFTER")) {
|
||||
|
|
@ -513,6 +555,8 @@ class VariableMonkeyResolution {
|
|||
vv = t->m_variableRequestCookiesNames.resolveFirst(var);
|
||||
} else if (comp(col, "FILES_TMPNAMES")) {
|
||||
vv = t->m_variableFilesTmpNames.resolveFirst(var);
|
||||
} else if (comp(col, "MULTIPART_PART_HEADERS")) {
|
||||
vv = t->m_variableMultipartPartHeaders.resolveFirst(var);
|
||||
} else if (comp(col, "TX")) {
|
||||
vv = t->m_collections.m_tx_collection->resolveFirst(var);
|
||||
} else if (comp(col, "RESOURCE")) {
|
||||
|
|
@ -608,7 +652,7 @@ class Variables : public std::vector<Variable *> {
|
|||
public:
|
||||
bool contains(Variable *v) {
|
||||
return std::find_if(begin(), end(),
|
||||
[v](Variable *m) -> bool { return *v == *m; }) != end();
|
||||
[v](const Variable *m) -> bool { return *v == *m; }) != end();
|
||||
};
|
||||
bool contains(const VariableValue *v) {
|
||||
return std::find_if(begin(), end(),
|
||||
|
|
|
|||
|
|
@ -53,14 +53,11 @@ duplicateBranch:src/request_body_processor/multipart.cc:93
|
|||
danglingTempReference:src/modsecurity.cc:206
|
||||
knownConditionTrueFalse:src/operators/validate_url_encoding.cc:77
|
||||
knownConditionTrueFalse:src/operators/verify_svnr.cc:87
|
||||
rethrowNoCurrentException:headers/modsecurity/transaction.h:309
|
||||
rethrowNoCurrentException:headers/modsecurity/transaction.h:313
|
||||
rethrowNoCurrentException:src/rule_with_actions.cc:127
|
||||
ctunullpointer:src/rule_with_actions.cc:241
|
||||
ctunullpointer:src/rule_with_actions.cc:244
|
||||
ctunullpointer:src/rule_with_operator.cc:135
|
||||
ctunullpointer:src/rule_with_operator.cc:95
|
||||
passedByValue:src/variables/global.h:109
|
||||
passedByValue:src/variables/global.h:110
|
||||
passedByValue:src/parser/driver.cc:46
|
||||
passedByValue:test/common/modsecurity_test.cc:49
|
||||
passedByValue:test/common/modsecurity_test.cc:98
|
||||
unreadVariable:src/rule_with_operator.cc:219
|
||||
|
|
@ -68,28 +65,33 @@ unreadVariable:src/rule_with_operator.cc:219
|
|||
uninitvar:src/operators/verify_cpf.cc:77
|
||||
uninitvar:src/operators/verify_svnr.cc:67
|
||||
|
||||
functionConst:src/collection/backend/lmdb.h:86
|
||||
unusedLabel:src/collection/backend/lmdb.cc:297
|
||||
|
||||
variableScope:src/operators/rx.cc
|
||||
variableScope:src/operators/rx_global.cc
|
||||
|
||||
noExplicitConstructor:seclang-parser.hh
|
||||
constParameter:seclang-parser.hh
|
||||
accessMoved:seclang-parser.hh
|
||||
returnTempReference:seclang-parser.hh
|
||||
|
||||
unreadVariable:src/operators/rx.cc
|
||||
unreadVariable:src/operators/rx_global.cc
|
||||
|
||||
|
||||
unusedFunction
|
||||
missingIncludeSystem
|
||||
useStlAlgorithm
|
||||
preprocessorErrorDirective
|
||||
funcArgNamesDifferent
|
||||
unmatchedSuppression
|
||||
missingInclude
|
||||
|
||||
purgedConfiguration
|
||||
|
||||
constParameter
|
||||
|
||||
nullPointerRedundantCheck
|
||||
knownConditionTrueFalse
|
||||
cstyleCast
|
||||
functionStatic
|
||||
variableScope
|
||||
shadowFunction
|
||||
|
||||
constVariable
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
127.0.0.1
|
||||
|
||||
# Comment line
|
||||
10.10.10.1
|
||||
::1
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
function main()
|
||||
local d = m.getvars("ARGS");
|
||||
local size = #d;
|
||||
m.log(9,"ARGS count read =" .. tostring(size));
|
||||
|
||||
ret = nil
|
||||
|
||||
if ( #d == 2 ) then
|
||||
return nil
|
||||
end
|
||||
|
||||
return "Unexpected result"
|
||||
end
|
||||
|
|
@ -253,14 +253,14 @@
|
|||
"body": ""
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "\\[msg \"testmsg\"\\]",
|
||||
"audit_log": "\\[msg \"testmsg\"\\] \\[data \"testdata\"\\] \\[severity \"7\"\\] \\[ver \"\"\\] \\[maturity \"0\"\\] \\[accuracy \"0\"\\] \\[tag \"testtag1\"\\] \\[tag \"testtag2\"\\]",
|
||||
"error_log": "",
|
||||
"http_code": 403
|
||||
},
|
||||
"rules": [
|
||||
"SecRuleEngine On",
|
||||
"SecDefaultAction \"phase:1,nolog,auditlog,deny,status:403\"",
|
||||
"SecRule ARGS \"@contains test2\" \"id:1557,phase:1,multiMatch,block,log,t:none,t:urlDecode,t:lowercase,msg:'testmsg'\"",
|
||||
"SecRule ARGS \"@contains test2\" \"id:1557,phase:1,multiMatch,block,log,t:none,t:urlDecode,t:lowercase,msg:'testmsg',logdata:'testdata',severity:'DEBUG',tag:'testtag1',tag:'testtag2'\"",
|
||||
"SecAuditEngine RelevantOnly",
|
||||
"SecAuditLogParts ABCFHZ",
|
||||
"SecAuditLog /tmp/test/modsec_audit_multimatch_1.log",
|
||||
|
|
@ -302,14 +302,14 @@
|
|||
"body": ""
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "\\[msg \"tstmsg\"\\]",
|
||||
"audit_log": "\\[msg \"testmsg\"\\] \\[data \"testdata\"\\] \\[severity \"7\"\\] \\[ver \"\"\\] \\[maturity \"0\"\\] \\[accuracy \"0\"\\] \\[tag \"testtag1\"\\] \\[tag \"testtag2\"\\]",
|
||||
"error_log": "",
|
||||
"http_code": 403
|
||||
},
|
||||
"rules": [
|
||||
"SecRuleEngine On",
|
||||
"SecDefaultAction \"phase:1,nolog,auditlog,deny,status:403\"",
|
||||
"SecRule ARGS \"@streq tEst2\" \"id:1558,phase:1,multiMatch,block,log,t:none,t:trim,t:lowercase,msg:'tstmsg'\"",
|
||||
"SecRule ARGS \"@streq tEst2\" \"id:1558,phase:1,multiMatch,block,log,t:none,t:trim,t:lowercase,msg:'testmsg',logdata:'testdata',severity:'DEBUG',tag:'testtag1',tag:'testtag2'\"",
|
||||
"SecAuditEngine RelevantOnly",
|
||||
"SecAuditLogParts ABCFHZ",
|
||||
"SecAuditLog /tmp/test/modsec_audit_multimatch_2.log",
|
||||
|
|
@ -318,5 +318,105 @@
|
|||
"SecAuditLogType Serial",
|
||||
"SecAuditLogRelevantStatus \"^(?:5|4(?!04))\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"enabled": 1,
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "auditlog : rule chain, multiMatch data, match after last transform",
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "www.modsecurity.org",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
"Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8",
|
||||
"Accept-Language": "en-us,en;q=0.5",
|
||||
"Accept-Encoding": "gzip,deflate",
|
||||
"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
|
||||
"Keep-Alive": "300",
|
||||
"Connection": "keep-alive",
|
||||
"Pragma": "no-cache",
|
||||
"Cache-Control": "no-cache"
|
||||
},
|
||||
"uri": "\/test.pl?param1=test¶m2=tEst2",
|
||||
"method": "GET",
|
||||
"http_version": 1.1,
|
||||
"body": ""
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "\\[msg \"testmsg\"\\] \\[data \"testdata\"\\] \\[severity \"7\"\\] \\[ver \"\"\\] \\[maturity \"0\"\\] \\[accuracy \"0\"\\] \\[tag \"testtag1\"\\] \\[tag \"testtag2\"\\]",
|
||||
"error_log": "",
|
||||
"http_code": 403
|
||||
},
|
||||
"rules": [
|
||||
"SecRuleEngine On",
|
||||
"SecDefaultAction \"phase:1,nolog,auditlog,deny,status:403\"",
|
||||
"SecRule ARGS \"@contains test2\" \"id:1559,phase:1,multiMatch,block,log,t:none,t:urlDecode,t:lowercase,msg:'testmsg',logdata:'testdata',severity:'DEBUG',tag:'testtag1',tag:'testtag2',chain\"",
|
||||
"SecRule REQUEST_METHOD \"@streq GET\" \"t:none\"",
|
||||
"SecAuditEngine RelevantOnly",
|
||||
"SecAuditLogParts ABCFHZ",
|
||||
"SecAuditLog /tmp/test/modsec_audit_multimatch_3.log",
|
||||
"SecAuditLogDirMode 0766",
|
||||
"SecAuditLogFileMode 0666",
|
||||
"SecAuditLogType Serial",
|
||||
"SecAuditLogRelevantStatus \"^(?:5|4(?!04))\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"enabled": 1,
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "auditlog : rule chain, multiMatch data, match only after intermediate transform",
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "www.modsecurity.org",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
"Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8",
|
||||
"Accept-Language": "en-us,en;q=0.5",
|
||||
"Accept-Encoding": "gzip,deflate",
|
||||
"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
|
||||
"Keep-Alive": "300",
|
||||
"Connection": "keep-alive",
|
||||
"Pragma": "no-cache",
|
||||
"Cache-Control": "no-cache"
|
||||
},
|
||||
"uri": "\/test.pl?param1=test¶m2=%20tEst2",
|
||||
"method": "GET",
|
||||
"http_version": 1.1,
|
||||
"body": ""
|
||||
},
|
||||
"expected": {
|
||||
"audit_log": "\\[msg \"testmsg\"\\] \\[data \"testdata\"\\] \\[severity \"7\"\\] \\[ver \"\"\\] \\[maturity \"0\"\\] \\[accuracy \"0\"\\] \\[tag \"testtag1\"\\] \\[tag \"testtag2\"\\]",
|
||||
"error_log": "",
|
||||
"http_code": 403
|
||||
},
|
||||
"rules": [
|
||||
"SecRuleEngine On",
|
||||
"SecDefaultAction \"phase:1,nolog,auditlog,deny,status:403\"",
|
||||
"SecRule ARGS \"@streq tEst2\" \"id:1560,phase:1,multiMatch,block,log,t:none,t:trim,t:lowercase,msg:'testmsg',logdata:'testdata',severity:'DEBUG',tag:'testtag1',tag:'testtag2',chain\"",
|
||||
"SecRule REQUEST_METHOD \"@streq GET\" \"t:none\"",
|
||||
"SecAuditEngine RelevantOnly",
|
||||
"SecAuditLogParts ABCFHZ",
|
||||
"SecAuditLog /tmp/test/modsec_audit_multimatch_4.log",
|
||||
"SecAuditLogDirMode 0766",
|
||||
"SecAuditLogFileMode 0666",
|
||||
"SecAuditLogType Serial",
|
||||
"SecAuditLogRelevantStatus \"^(?:5|4(?!04))\""
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing LUA :: m.set TX (1/6)",
|
||||
"title":"Testing LUA :: m.set TX (1/7)",
|
||||
"resource":"lua",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing LUA :: m.set IP (2/6)",
|
||||
"title":"Testing LUA :: m.set IP (2/7)",
|
||||
"resource":"lua",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
|
|
@ -86,7 +86,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing LUA :: m.set GLOBAL (3/6)",
|
||||
"title":"Testing LUA :: m.set GLOBAL (3/7)",
|
||||
"resource":"lua",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
|
|
@ -128,7 +128,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing LUA :: m.set RESOURCE (4/6)",
|
||||
"title":"Testing LUA :: m.set RESOURCE (4/7)",
|
||||
"resource":"lua",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
|
|
@ -170,7 +170,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing LUA :: m.set SESSION (5/6)",
|
||||
"title":"Testing LUA :: m.set SESSION (5/7)",
|
||||
"resource":"lua",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
|
|
@ -212,7 +212,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing LUA :: m.set USER (6/6)",
|
||||
"title":"Testing LUA :: m.set USER (6/7)",
|
||||
"resource":"lua",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
|
|
@ -250,5 +250,43 @@
|
|||
"SecRuleScript test-cases/data/setvar.lua \"id:2,pass\"",
|
||||
"SecRule USER.lua_set_var \"@contains 2\" \"id:3,t:none\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing LUA :: m.getvars ARGS (8/8)",
|
||||
"resource":"lua",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
},
|
||||
"server":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":80
|
||||
},
|
||||
"request":{
|
||||
"headers":{
|
||||
"Host":"localhost",
|
||||
"User-Agent":"My sweet little browser",
|
||||
"Accept":"*/*",
|
||||
"Content-Length": "0"
|
||||
},
|
||||
"uri":"/whee?parm1=a&parm2=b",
|
||||
"method":"GET",
|
||||
"body": [ ]
|
||||
},
|
||||
"response":{
|
||||
"headers":{},
|
||||
"body":[
|
||||
"no need."
|
||||
]
|
||||
},
|
||||
"expected":{
|
||||
"http_code": 200
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
"SecRuleScript test-cases/data/match-getvars-args.lua \"id:2,phase:2,deny,status:403\""
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Include (1/7)",
|
||||
"title":"Include (1/8)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Include (2/7)",
|
||||
"title":"Include (2/8)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Include (3/7)",
|
||||
"title":"Include (3/8)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
|
|
@ -122,7 +122,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Include (4/7)",
|
||||
"title":"Include (4/8)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
|
|
@ -162,7 +162,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Include (5/7)",
|
||||
"title":"Include (5/8)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
|
|
@ -203,7 +203,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Include (6/7)",
|
||||
"title":"Include (6/8)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
|
|
@ -243,7 +243,7 @@
|
|||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Include (7/7)",
|
||||
"title":"Include (7/8)",
|
||||
"client":{
|
||||
"ip":"200.249.12.31",
|
||||
"port":123
|
||||
|
|
@ -279,5 +279,45 @@
|
|||
"Include test-cases/data/conasdffig_example2.txt",
|
||||
"SecRule ARGS \"@contains test\" \"id:9,pass,t:trim\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Include (8/8) -- quoted with wildcard",
|
||||
"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":"*/*"
|
||||
},
|
||||
"uri":"/?key=value&key=other_value",
|
||||
"method":"GET"
|
||||
},
|
||||
"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 \"Contains\" with param \"config_example2\" against ARGS."
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
"Include \"test-cases/data/config_ex*ple2.txt\"",
|
||||
"SecRule ARGS \"@contains test\" \"id:9,pass,t:trim\""
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -127,5 +127,140 @@
|
|||
"SecRuleEngine On",
|
||||
"SecRule REQUEST_HEADERS:Content-Type \"@rx a(b\" \"id:1,phase:2,pass,t:trim,block\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing Operator :: @rx with PCRE error",
|
||||
"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":"/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww",
|
||||
"method":"HEAD",
|
||||
"body": [ ]
|
||||
},
|
||||
"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":"rx: regex error 'MATCH_LIMIT' for pattern",
|
||||
"error_log":"Matched \"Operator `StrEq' with parameter `1' against variable `MSC_PCRE_ERROR'"
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
"SecPcreMatchLimit 2",
|
||||
"SecRule ARGS:rxtest \"@rx (w+)+$\" \"id:1,phase:1,pass,t:trim,block\"",
|
||||
"SecRule MSC_PCRE_ERROR \"@streq 1\" \"id:2,phase:1,pass,t:trim,block\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing Operator :: @rx with PCRE match limits exceeded",
|
||||
"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":"/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww",
|
||||
"method":"HEAD",
|
||||
"body": [ ]
|
||||
},
|
||||
"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":"rx: regex error 'MATCH_LIMIT' for pattern",
|
||||
"error_log":"Matched \"Operator `StrEq' with parameter `1' against variable `MSC_PCRE_LIMITS_EXCEEDED'"
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
"SecPcreMatchLimit 2",
|
||||
"SecRule ARGS:rxtest \"@rx (w+)+$\" \"id:1,phase:1,pass,t:trim,block\"",
|
||||
"SecRule MSC_PCRE_LIMITS_EXCEEDED \"@streq 1\" \"id:2,phase:1,pass,t:trim,block\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing Operator :: @rx with PCRE match limits exceeded",
|
||||
"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":"/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww",
|
||||
"method":"HEAD",
|
||||
"body": [ ]
|
||||
},
|
||||
"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":"rx: regex error 'MATCH_LIMIT' for pattern",
|
||||
"error_log":"Matched \"Operator `StrEq' with parameter `1' against variable `TX:MSC_PCRE_LIMITS_EXCEEDED'"
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
"SecPcreMatchLimit 2",
|
||||
"SecRule ARGS:rxtest \"@rx (w+)+$\" \"id:1,phase:1,pass,t:trim,block\"",
|
||||
"SecRule TX:MSC_PCRE_LIMITS_EXCEEDED \"@streq 1\" \"id:2,phase:1,pass,t:trim,block\""
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -162,6 +162,57 @@
|
|||
"SecRuleEngine On",
|
||||
"SecRule MULTIPART_PART_HEADERS:parm2 \"@rx content-type:.*jpeg\" \"phase:2,deny,status:403,id:500074,t:lowercase\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"enabled":1,
|
||||
"version_min":300000,
|
||||
"title":"Testing Variables :: MULTIPART_PART_HEADERS (check EOL)",
|
||||
"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":"249",
|
||||
"Content-Type":"multipart/form-data; boundary=-----------------------------69343412719991675451336310646",
|
||||
"Expect":"100-continue"
|
||||
},
|
||||
"uri":"/",
|
||||
"method":"POST",
|
||||
"body":[
|
||||
"-------------------------------69343412719991675451336310646",
|
||||
"Content-Disposition: form-data; name=\"file\"; filename=\"New Text Document.txt\"",
|
||||
"Content-Type: text/plain; charset=utf-8\r\n",
|
||||
"",
|
||||
"1",
|
||||
"-------------------------------69343412719991675451336310646--"
|
||||
]
|
||||
},
|
||||
"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":{
|
||||
"http_code": 200
|
||||
},
|
||||
"rules":[
|
||||
"SecRuleEngine On",
|
||||
"SecRule MULTIPART_PART_HEADERS \"@rx ^content-type\\s*+:\\s*+(.*)$\" \"id:922110,phase:2,deny,capture,t:none,t:lowercase,chain\"",
|
||||
"SecRule TX:1 \"!@rx ^text/plain; charset=(?:iso-8859-15?|windows-1252|utf-8)$\" \"t:lowercase\""
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue