mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
Compare commits
175 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a07ed61e74 | ||
|
4e2788eb47 | ||
|
f9f4011a4b | ||
|
62cb73f31d | ||
|
8b3269f4d1 | ||
|
e879711d87 | ||
|
9fea1ca454 | ||
|
47bc24a808 | ||
|
12809656a6 | ||
|
ea51a663f1 | ||
|
d19d3b4785 | ||
|
67f32a4e63 | ||
|
6c6d94fc66 | ||
|
0f402f33fd | ||
|
01c427f6be | ||
|
31fb9390c2 | ||
|
2ee45de2fc | ||
|
0ac551b070 | ||
|
013c8c2c7b | ||
|
d8574c8c08 | ||
|
37948704df | ||
|
28bc3a98df | ||
|
72e3abdd12 | ||
|
f2170d8576 | ||
|
c60709a58c | ||
|
1ff9f2a943 | ||
|
690355b297 | ||
|
78b9cb7b57 | ||
|
5d05ba359c | ||
|
9fb75d2c9a | ||
|
abed778b4a | ||
|
8d15991fb4 | ||
|
b8a22bb67a | ||
|
7e3c807c0d | ||
|
bb70ff06a4 | ||
|
08b70e006b | ||
|
79d55037c0 | ||
|
9a8ce8b5f5 | ||
|
cf24aeaead | ||
|
6089b6b06b | ||
|
31507404e6 | ||
|
f64ea2a708 | ||
|
1362479d34 | ||
|
8d3b2cacc4 | ||
|
a17193f7af | ||
|
de624f9460 | ||
|
7660125da6 | ||
|
0caf30679f | ||
|
0bcabf3208 | ||
|
aab47091b1 | ||
|
990d99b1fb | ||
|
220caa5abc | ||
|
a3876e3c99 | ||
|
d228ea6607 | ||
|
89442ede16 | ||
|
e8dc60ee06 | ||
|
bf707de08f | ||
|
0b62b7eb85 | ||
|
91a45e79bd | ||
|
2135c8934e | ||
|
8947346cd4 | ||
|
67429307cc | ||
|
0c7ea21a26 | ||
|
72de7e8400 | ||
|
0bf60208af | ||
|
2000f4c048 | ||
|
159f6120aa | ||
|
bbe7eda693 | ||
|
0fcd257fc4 | ||
|
fedc70983c | ||
|
5b1c6fbf68 | ||
|
eedfed873e | ||
|
f0aa0700fe | ||
|
90be54e25e | ||
|
3dc9fe990c | ||
|
e3678764e5 | ||
|
22fee1296d | ||
|
b82d600049 | ||
|
797f7dc4b2 | ||
|
6408bf9237 | ||
|
37c0de363e | ||
|
029684c294 | ||
|
3e95614699 | ||
|
b42602f400 | ||
|
8ae8374be5 | ||
|
f62de58632 | ||
|
9e41a53760 | ||
|
01a0615887 | ||
|
80019da75e | ||
|
7a986c7bae | ||
|
8f00f4700f | ||
|
42280d213d | ||
|
c3c2c6f280 | ||
|
dbdd6318ff | ||
|
d3c1ad7177 | ||
|
dc40880663 | ||
|
1a2b13967f | ||
|
a555e5a445 | ||
|
646881085c | ||
|
29c3cc32e1 | ||
|
c82e831b66 | ||
|
f96806cd28 | ||
|
71037dc4d7 | ||
|
d68aef320c | ||
|
b97b61b711 | ||
|
40af573759 | ||
|
199056b916 | ||
|
9e685bf86d | ||
|
9158477561 | ||
|
4c5bc45dfd | ||
|
f260a75c14 | ||
|
6a2eee629c | ||
|
d9acf3d0cd | ||
|
eb7e2b8a5f | ||
|
a332567b85 | ||
|
72bb873460 | ||
|
849131c8cf | ||
|
d76f3e741e | ||
|
900e7bcd06 | ||
|
10d1c2be74 | ||
|
e92507868e | ||
|
784cf0b64c | ||
|
c0681b6239 | ||
|
7b4c3a2c0f | ||
|
17700eca5b | ||
|
a07d0c7d34 | ||
|
106ed22b6d | ||
|
c6433df7b2 | ||
|
4fb22466a0 | ||
|
d9101a4fe1 | ||
|
daf550ef5f | ||
|
db7e4cb67b | ||
|
fd4564131f | ||
|
530919439b | ||
|
41fd21b0fb | ||
|
d422b36966 | ||
|
4a720004dd | ||
|
42a401892b | ||
|
5bec188146 | ||
|
742f97ccc0 | ||
|
29a86b17df | ||
|
aca93f568e | ||
|
7ec50eb53f | ||
|
4e68edf0e5 | ||
|
cdaf32f521 | ||
|
ce9a3167fa | ||
|
b0497d9cb9 | ||
|
d1e7e7b4f2 | ||
|
2fb446ab2d | ||
|
bbef22b3b5 | ||
|
d053ec6de6 | ||
|
c2b86ddc49 | ||
|
7d9c80dede | ||
|
da38f20e19 | ||
|
1eed8b9288 | ||
|
193a0002e4 | ||
|
e0c58233ad | ||
|
ec506daaef | ||
|
0613ceeb75 | ||
|
99ce9779e6 | ||
|
75d31a4d1e | ||
|
b7b2d9a40d | ||
|
4df297b596 | ||
|
e313ac7de7 | ||
|
9a1155ca26 | ||
|
373ddb8925 | ||
|
63201ae39f | ||
|
7737594edf | ||
|
9238b0ced0 | ||
|
c6c06c4f33 | ||
|
9e02b3cf01 | ||
|
6ecfee7ab7 | ||
|
2c613fb77c | ||
|
2ad87f640f | ||
|
2ec640fd76 |
30
.github/workflows/ci.yml
vendored
30
.github/workflows/ci.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
- {label: "wo geoip", opt: "--without-geoip" }
|
||||
- {label: "wo ssdeep", opt: "--without-ssdeep" }
|
||||
- {label: "with lmdb", opt: "--with-lmdb" }
|
||||
- {label: "with pcre2", opt: "--with-pcre2" }
|
||||
- {label: "with pcre", opt: "--with-pcre" }
|
||||
exclude:
|
||||
- platform: {label: "x32"}
|
||||
configure: {label: "wo geoip"}
|
||||
@ -88,7 +88,7 @@ jobs:
|
||||
- {label: "wo geoip", opt: "--without-geoip" }
|
||||
- {label: "wo ssdeep", opt: "--without-ssdeep" }
|
||||
- {label: "with lmdb", opt: "--with-lmdb" }
|
||||
- {label: "with pcre2", opt: "--with-pcre2" }
|
||||
- {label: "with pcre", opt: "--with-pcre" }
|
||||
steps:
|
||||
- name: Setup Dependencies
|
||||
# curl, pcre2 not installed because they're already
|
||||
@ -102,7 +102,6 @@ jobs:
|
||||
lua \
|
||||
libmaxminddb \
|
||||
libxml2 \
|
||||
geoip \
|
||||
ssdeep \
|
||||
pcre \
|
||||
bison \
|
||||
@ -111,6 +110,16 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: Build GeoIP
|
||||
run: |
|
||||
git clone --depth 1 --no-checkout https://github.com/maxmind/geoip-api-c.git
|
||||
cd geoip-api-c
|
||||
git fetch --tags
|
||||
# Check out the last release, v1.6.12
|
||||
git checkout 4b526e7331ca1d692b74a0509ddcc725622ed31a
|
||||
autoreconf --install
|
||||
./configure --disable-dependency-tracking --disable-silent-rules --prefix=/opt/homebrew
|
||||
make install
|
||||
- name: build.sh
|
||||
run: ./build.sh
|
||||
- name: configure
|
||||
@ -178,20 +187,21 @@ jobs:
|
||||
ctest -C ${{ matrix.configuration }} --output-on-failure
|
||||
|
||||
cppcheck:
|
||||
runs-on: [ubuntu-22.04]
|
||||
runs-on: [macos-14]
|
||||
steps:
|
||||
- name: Setup Dependencies
|
||||
run: |
|
||||
sudo apt-get update -y -qq
|
||||
sudo apt-get install -y cppcheck
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v4
|
||||
brew install autoconf \
|
||||
automake \
|
||||
libtool \
|
||||
cppcheck
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: Configure libModSecurity
|
||||
- name: configure
|
||||
run: |
|
||||
./build.sh
|
||||
./configure
|
||||
- name: Run cppcheck on libModSecurity
|
||||
- name: cppcheck
|
||||
run: make check-static
|
||||
|
40
CHANGES
40
CHANGES
@ -1,3 +1,43 @@
|
||||
v3.0.14 - 2025-Feb-25
|
||||
---------------------
|
||||
|
||||
- [fix: fixed htmlEntityDecode methods]
|
||||
[PR from private repo - @theseion,@airween; fixed CVE-2025-27110]
|
||||
- fix: Added missing header to avoid build error with gcc-15
|
||||
[PR #3342 - @airween]
|
||||
- Fix for issue #3334: build not finding YAJL
|
||||
[PR #3335 - @RooHTaylor]
|
||||
- fix: add value checking to @validateByteRange
|
||||
[PR #3322 - @airween]
|
||||
- fix: build library on OSX without GeoIP brew package
|
||||
[PR #3319 - @theseion,@airween]
|
||||
- Update README.md
|
||||
[PR #3314 - @ElevationsRPG]
|
||||
- Fix: Add false positive cppcheck-suppress for compatibility with upda…
|
||||
[PR #3307 - @gberkes]
|
||||
- fix: align TIME_MON variable's behavior
|
||||
[PR #3306 - @M4tteoP,@theseion,@airween]
|
||||
- Fix m_requestHostName variable behavior
|
||||
[PR #3298 - @airween]
|
||||
- Add regression rules for test
|
||||
[PR #3291 - @hnakamur]
|
||||
- Fix modsecurity-regression-test-secremoterules.txt URL in example
|
||||
[PR #3287 - @hnakamur]
|
||||
- Use latest version of cppcheck (2.15.0) to analyze codebase
|
||||
[PR #3283 - @eduar-hte]
|
||||
- Replace usage of range-checked 'at' method when vector/string has already been size checked
|
||||
[PR #3280 - @eduar-hte]
|
||||
- chore: add 'log' action to rule 200005
|
||||
[PR #3266 - @airween]
|
||||
- docs: add a logo picture for github dark theme
|
||||
[PR #3264 - @xuruidong]
|
||||
- Leverage std::make_unique & std::make_shared to create objects in the heap
|
||||
[PR #3254 - @eduar-hte]
|
||||
- Simplified handling of RuleMessage by removing usage of std::shared_ptr
|
||||
[PR #3253 - @eduar-hte]
|
||||
- Simplified constructors, copy constructors & assignment operators
|
||||
[PR #3248 - @eduar-hte]
|
||||
|
||||
v3.0.13 - 2024-Sep-03
|
||||
---------------------
|
||||
|
||||
|
@ -63,9 +63,11 @@ cppcheck:
|
||||
--enable=warning,style,performance,portability,unusedFunction,missingInclude \
|
||||
--inconclusive \
|
||||
--template="warning: {file},{line},{severity},{id},{message}" \
|
||||
-I headers -I . -I others -I src -I others/mbedtls/include -I src/parser \
|
||||
-I headers -I . -I $(top_srcdir)/others -I $(top_srcdir)/src -I $(top_srcdir)/others/mbedtls/include \
|
||||
--error-exitcode=1 \
|
||||
-i "src/parser/seclang-parser.cc" -i "src/parser/seclang-scanner.cc" \
|
||||
-i others \
|
||||
--std=c++17 \
|
||||
--force --verbose .
|
||||
|
||||
|
||||
|
10
README.md
10
README.md
@ -1,5 +1,9 @@
|
||||
|
||||
<img src="https://github.com/owasp-modsecurity/ModSecurity/raw/v3/master/others/modsec.png" width="50%">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./others/modsec_white_bg.png">
|
||||
<source media="(prefers-color-scheme: light)" srcset="./others/modsec.png">
|
||||
<img src="./others/modsec.png" width="50%">
|
||||
</picture>
|
||||
|
||||

|
||||
[](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)
|
||||
@ -215,8 +219,8 @@ the utilities, follow the commands listed below:
|
||||
$ cd /path/to/your/ModSecurity
|
||||
$ git submodule foreach git pull
|
||||
$ cd test
|
||||
$ ./regression-tests
|
||||
$ ./unit-tests
|
||||
$ ./regression_tests
|
||||
$ ./unit_tests
|
||||
```
|
||||
|
||||
### Debugging
|
||||
|
@ -21,8 +21,8 @@ AC_ARG_WITH(
|
||||
[test_paths="${with_pcre}"],
|
||||
[test_paths="/usr/local/libpcre /usr/local/pcre /usr/local /opt/libpcre /opt/pcre /opt /usr /opt/local"])
|
||||
|
||||
if test "x${with_pcre2}" != "x" && test "x${with_pcre2}" != "xno"; then
|
||||
AC_MSG_NOTICE([pcre2 specified; omitting check for pcre])
|
||||
if test "x${with_pcre}" == "x" && test "x${with_pcre}" != "xno"; then
|
||||
AC_MSG_NOTICE([Support for pcre not requested; omitting check for pcre])
|
||||
else
|
||||
|
||||
AC_MSG_CHECKING([for libpcre config script])
|
||||
@ -106,6 +106,7 @@ else
|
||||
LIBS=$save_LIBS
|
||||
fi
|
||||
|
||||
PCRE_CFLAGS="-DWITH_PCRE ${PCRE_CFLAGS}"
|
||||
AC_SUBST(PCRE_CONFIG)
|
||||
AC_SUBST(PCRE_VERSION)
|
||||
AC_SUBST(PCRE_CPPFLAGS)
|
||||
|
@ -29,10 +29,12 @@ if test "x${with_pcre2}" == "xno"; then
|
||||
AC_MSG_NOTICE([Support for PCRE2 was disabled by the utilization of --without-pcre2 or --with-pcre2=no])
|
||||
PCRE2_DISABLED=yes
|
||||
else
|
||||
if test "x${with_pcre2}" == "xyes"; then
|
||||
PCRE2_MANDATORY=yes
|
||||
AC_MSG_NOTICE([PCRE2 support was marked as mandatory by the utilization of --with-pcre2=yes])
|
||||
fi
|
||||
PCRE2_MANDATORY=yes
|
||||
AC_MSG_NOTICE([PCRE2 is enabled by default.])
|
||||
# if test "x${with_pcre2}" == "xyes"; then
|
||||
# PCRE2_MANDATORY=yes
|
||||
# AC_MSG_NOTICE([PCRE2 support was marked as mandatory by the utilization of --with-pcre2=yes])
|
||||
# fi
|
||||
# for x in ${PCRE2_POSSIBLE_LIB_NAMES}; do
|
||||
# CHECK_FOR_PCRE2_AT(${x})
|
||||
# if test -n "${PCRE2_VERSION}"; then
|
||||
@ -96,9 +98,14 @@ else
|
||||
AC_MSG_NOTICE([PCRE2 is disabled by default.])
|
||||
else
|
||||
PCRE2_FOUND=1
|
||||
AC_MSG_NOTICE([using PCRE2 v${PCRE2_VERSION}])
|
||||
PCRE2_CFLAGS="-DWITH_PCRE2 ${PCRE2_CFLAGS}"
|
||||
PCRE2_CFLAGS="${PCRE2_CFLAGS}"
|
||||
PCRE2_DISPLAY="${PCRE2_LDADD}, ${PCRE2_CFLAGS}"
|
||||
AC_MSG_NOTICE([using PCRE2_VERSION ${PCRE2_VERSION}])
|
||||
AC_MSG_NOTICE([using PCRE2_LDADD ${PCRE2_LDADD}])
|
||||
AC_MSG_NOTICE([using PCRE2_LIBS ${PCRE2_LIBS}])
|
||||
AC_MSG_NOTICE([using PCRE2_LDFLAGS ${PCRE2_LDFLAGS}])
|
||||
AC_MSG_NOTICE([using PCRE2_CFLAGS ${PCRE2_CFLAGS}])
|
||||
AC_MSG_NOTICE([using PCRE2_DISPLAY ${PCRE2_DISPLAY}])
|
||||
AC_SUBST(PCRE2_VERSION)
|
||||
AC_SUBST(PCRE2_LDADD)
|
||||
AC_SUBST(PCRE2_LIBS)
|
||||
|
@ -171,13 +171,13 @@ endfunction()
|
||||
|
||||
# unit tests
|
||||
file(GLOB unitTestSources ${BASE_DIR}/test/unit/*.cc)
|
||||
add_executable(unit_tests ${unitTestSources})
|
||||
add_executable(unit_tests ${unitTestSources} ${BASE_DIR}/test/common/custom_debug_log.cc)
|
||||
setTestTargetProperties(unit_tests)
|
||||
target_compile_options(unit_tests PRIVATE /wd4805)
|
||||
|
||||
# regression tests
|
||||
file(GLOB regressionTestsSources ${BASE_DIR}/test/regression/*.cc)
|
||||
add_executable(regression_tests ${regressionTestsSources})
|
||||
add_executable(regression_tests ${regressionTestsSources} ${BASE_DIR}/test/common/custom_debug_log.cc)
|
||||
setTestTargetProperties(regression_tests)
|
||||
|
||||
macro(add_regression_test_capability compile_definition flag)
|
||||
|
@ -18,7 +18,7 @@ The Windows build of libModSecurity uses Build Tools for Visual Studio 2022 (for
|
||||
* Windows SDK
|
||||
* CMake
|
||||
* Address Sanitizer
|
||||
* [Conan package manager 2.2.2](https://github.com/conan-io/conan/releases/download/2.2.2/conan-2.2.2-windows-x86_64-installer.exe)
|
||||
* [Conan package manager 2.10.2](https://github.com/conan-io/conan/releases/download/2.10.2/conan-2.10.2-windows-x86_64-installer.exe)
|
||||
* Install and then setup the default Conan profile to use the MSVC C++ compiler:
|
||||
1. Open a command-prompt and set the MSVC C++ compiler environment by executing: `C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat`
|
||||
2. Execute: `conan profile detect --force`
|
||||
@ -30,7 +30,7 @@ The Windows build of libModSecurity uses Build Tools for Visual Studio 2022 (for
|
||||
|
||||
## Build
|
||||
|
||||
Install the prerequisites listsed in the previous section, checkout libModSecurity and from the directory where it's located execute:
|
||||
Install the prerequisites listed in the previous section, checkout libModSecurity and from the directory where it's located execute:
|
||||
|
||||
```
|
||||
vcbuild.bat [build_configuration] [arch] [USE_ASAN]
|
||||
|
@ -35,7 +35,7 @@ RUN %INSTALLER% /SP- /VERYSILENT /SUPPRESSMSGBOXES /NOCANCEL `
|
||||
/NORESTART /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /LOADINF=git.inf
|
||||
|
||||
# download & setup conan
|
||||
ARG CONAN_VERSION=2.2.2
|
||||
ARG CONAN_VERSION=2.10.2
|
||||
ARG CONAN_BINARY=conan-${CONAN_VERSION}-windows-x86_64-installer.exe
|
||||
ARG CONAN_URL=https://github.com/conan-io/conan/releases/download/${CONAN_VERSION}/${CONAN_BINARY}
|
||||
|
||||
|
@ -62,7 +62,7 @@ else
|
||||
YAJL_DISPLAY="${YAJL_LDADD}, ${YAJL_CFLAGS}"
|
||||
else
|
||||
# If pkg-config did not find anything useful, go over file lookup.
|
||||
for x in ${YAJL_POSSIBLE_LIB_NAMES}; do
|
||||
for x in ${YAJL_POSSIBLE_PATHS}; do
|
||||
CHECK_FOR_YAJL_AT(${x})
|
||||
if test -n "${YAJL_VERSION}"; then
|
||||
break
|
||||
|
36
configure.ac
36
configure.ac
@ -42,7 +42,7 @@ AC_PREFIX_DEFAULT([/usr/local/modsecurity])
|
||||
|
||||
|
||||
# General automake options.
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
|
||||
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
|
||||
|
||||
|
||||
# Check for dependencies (C++, AR, Lex, Yacc and Make)
|
||||
@ -109,24 +109,19 @@ AM_CONDITIONAL([YAJL_VERSION], [test "$YAJL_VERSION" != ""])
|
||||
|
||||
# Check for LibGeoIP
|
||||
PROG_GEOIP
|
||||
AM_CONDITIONAL([GEOIP_CFLAGS], [test "GEOIP_CFLAGS" != ""])
|
||||
|
||||
# Check for MaxMind
|
||||
PROG_MAXMIND
|
||||
AM_CONDITIONAL([MAXMIND_CFLAGS], [test "MAXMIND_CFLAGS" != ""])
|
||||
|
||||
|
||||
# Check for LMDB
|
||||
PROG_LMDB
|
||||
AM_CONDITIONAL([LMDB_CFLAGS], [test "LMDB_CFLAGS" != ""])
|
||||
|
||||
# Check for SSDEEP
|
||||
CHECK_SSDEEP
|
||||
AM_CONDITIONAL([SSDEEP_CFLAGS], [test "SSDEEP_CFLAGS" != ""])
|
||||
|
||||
# Check for LUA
|
||||
CHECK_LUA
|
||||
AM_CONDITIONAL([LUA_CFLAGS], [test "LUA_CFLAGS" != ""])
|
||||
|
||||
|
||||
#
|
||||
@ -146,16 +141,16 @@ CHECK_LIBXML2
|
||||
|
||||
|
||||
#
|
||||
# Check for libpcre
|
||||
# Check for libpcre only if explicitly requested
|
||||
#
|
||||
CHECK_PCRE
|
||||
|
||||
|
||||
#
|
||||
# Check for pcre2
|
||||
#
|
||||
PROG_PCRE2
|
||||
AM_CONDITIONAL([PCRE2_CFLAGS], [test "PCRE2_CFLAGS" != ""])
|
||||
if test "x${with_pcre}" != "x" && test "x${with_pcre}" != "xno"; then
|
||||
CHECK_PCRE
|
||||
else
|
||||
#
|
||||
# Check for pcre2
|
||||
#
|
||||
PROG_PCRE2
|
||||
fi
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
@ -587,6 +582,17 @@ if test "x$LUA_FOUND" = "x2"; then
|
||||
echo " + LUA ....disabled"
|
||||
fi
|
||||
|
||||
##PCRE
|
||||
if test "x${with_pcre}" != "x" \
|
||||
&& test "x${with_pcre}" != "xno" \
|
||||
&& test "x${PCRE_VERSION}" == "x"; then
|
||||
AC_MSG_NOTICE([*** pcre library not found.])
|
||||
else
|
||||
echo " + PCRE ....found "
|
||||
echo " using pcre v${PCRE_VERSION}"
|
||||
echo " ${PCRE_LDADD}, ${PCRE_CFLAGS}"
|
||||
fi
|
||||
|
||||
|
||||
## PCRE2
|
||||
if test "x$PCRE2_FOUND" = "x0"; then
|
||||
|
@ -38,7 +38,7 @@ RulesSet *rules = NULL;
|
||||
ModSecurity *modsec = NULL;
|
||||
|
||||
|
||||
void process_special_request (int j) {
|
||||
static void process_special_request (int j) {
|
||||
Transaction *transaction;
|
||||
transaction = msc_new_transaction(modsec, rules, NULL);
|
||||
|
||||
@ -60,7 +60,7 @@ void process_special_request (int j) {
|
||||
msc_transaction_cleanup(transaction);
|
||||
}
|
||||
|
||||
void process_request (int j) {
|
||||
static void process_request (int j) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < REQUESTS_PER_PROCESS; i++) {
|
||||
|
@ -14,6 +14,7 @@ multithread_LDADD = \
|
||||
$(MAXMIND_LDADD) \
|
||||
$(LUA_LDADD) \
|
||||
$(PCRE_LDADD) \
|
||||
$(PCRE2_LDADD) \
|
||||
$(SSDEEP_LDADD) \
|
||||
$(YAJL_LDADD)
|
||||
|
||||
@ -46,6 +47,7 @@ multithread_CPPFLAGS = \
|
||||
$(LMDB_CFLAGS) \
|
||||
$(LUA_CFLAGS) \
|
||||
$(PCRE_CFLAGS) \
|
||||
$(PCRE2_CFLAGS) \
|
||||
$(LIBXML2_CFLAGS)
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@ int main (int argc, char *argv[]) {
|
||||
modsec->setConnectorInformation("ModSecurity-test v0.0.1-alpha (Simple " \
|
||||
"example on how to use ModSecurity API");
|
||||
|
||||
char main_rule_uri[] = "basic_rules.conf";
|
||||
const char main_rule_uri[] = "basic_rules.conf";
|
||||
auto rules = std::make_unique<modsecurity::RulesSet>();
|
||||
if (rules->loadFromUri(main_rule_uri) < 0) {
|
||||
std::cerr << "Problems loading the rules..." << std::endl;
|
||||
|
@ -14,6 +14,7 @@ simple_request_LDADD = \
|
||||
$(MAXMIND_LDADD) \
|
||||
$(LUA_LDADD) \
|
||||
$(PCRE_LDADD) \
|
||||
$(PCRE2_LDADD) \
|
||||
$(SSDEEP_LDADD) \
|
||||
$(YAJL_LDADD)
|
||||
|
||||
@ -46,6 +47,7 @@ simple_request_CPPFLAGS = \
|
||||
$(LMDB_CFLAGS) \
|
||||
$(LUA_CFLAGS) \
|
||||
$(PCRE_CFLAGS) \
|
||||
$(PCRE2_CFLAGS) \
|
||||
$(LIBXML2_CFLAGS)
|
||||
|
||||
|
||||
|
@ -155,18 +155,18 @@ class ReadingLogsViaRuleMessage {
|
||||
const modsecurity::RuleMessage *ruleMessage = \
|
||||
reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev);
|
||||
|
||||
std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId);
|
||||
std::cout << " phase: " << std::to_string(ruleMessage->m_phase);
|
||||
std::cout << "Rule Id: " << std::to_string(ruleMessage->m_rule.m_ruleId);
|
||||
std::cout << " phase: " << std::to_string(ruleMessage->getPhase());
|
||||
std::cout << std::endl;
|
||||
if (ruleMessage->m_isDisruptive) {
|
||||
std::cout << " * Disruptive action: ";
|
||||
std::cout << modsecurity::RuleMessage::log(ruleMessage);
|
||||
std::cout << modsecurity::RuleMessage::log(*ruleMessage);
|
||||
std::cout << std::endl;
|
||||
std::cout << " ** %d is meant to be informed by the webserver.";
|
||||
std::cout << std::endl;
|
||||
} else {
|
||||
std::cout << " * Match, but no disruptive action: ";
|
||||
std::cout << modsecurity::RuleMessage::log(ruleMessage);
|
||||
std::cout << modsecurity::RuleMessage::log(*ruleMessage);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ read_LDADD = \
|
||||
$(LMDB_LDADD) \
|
||||
$(LUA_LDADD) \
|
||||
$(PCRE_LDADD) \
|
||||
$(PCRE2_LDADD) \
|
||||
$(SSDEEP_LDADD) \
|
||||
$(YAJL_LDADD)
|
||||
|
||||
@ -46,6 +47,7 @@ read_CPPFLAGS = \
|
||||
$(LMDB_CFLAGS) \
|
||||
$(LUA_CFLAGS) \
|
||||
$(PCRE_CFLAGS) \
|
||||
$(PCRE2_CFLAGS) \
|
||||
$(LIBXML2_CFLAGS)
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ int main (int argc, char **argv)
|
||||
msc_rules_dump(rules);
|
||||
|
||||
ret = msc_rules_add_remote(rules, "test",
|
||||
"https://www.modsecurity.org/modsecurity-regression-test-secremoterules.txt",
|
||||
"https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/refs/heads/v3/master/test/modsecurity-regression-rules.txt",
|
||||
&error);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Problems loading the rules --\n");
|
||||
|
@ -14,6 +14,7 @@ simple_request_LDADD = \
|
||||
$(LMDB_LDADD) \
|
||||
$(LUA_LDADD) \
|
||||
$(PCRE_LDADD) \
|
||||
$(PCRE2_LDADD) \
|
||||
$(SSDEEP_LDADD) \
|
||||
$(YAJL_LDADD)
|
||||
|
||||
@ -46,6 +47,7 @@ simple_request_CPPFLAGS = \
|
||||
$(LMDB_CFLAGS) \
|
||||
$(LUA_CFLAGS) \
|
||||
$(PCRE_CFLAGS) \
|
||||
$(PCRE2_CFLAGS) \
|
||||
$(LIBXML2_CFLAGS)
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
|
@ -76,18 +76,18 @@ static void logCb(void *data, const void *ruleMessagev) {
|
||||
const modsecurity::RuleMessage *ruleMessage = \
|
||||
reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev);
|
||||
|
||||
std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId);
|
||||
std::cout << " phase: " << std::to_string(ruleMessage->m_phase);
|
||||
std::cout << "Rule Id: " << std::to_string(ruleMessage->m_rule.m_ruleId);
|
||||
std::cout << " phase: " << std::to_string(ruleMessage->getPhase());
|
||||
std::cout << std::endl;
|
||||
if (ruleMessage->m_isDisruptive) {
|
||||
std::cout << " * Disruptive action: ";
|
||||
std::cout << modsecurity::RuleMessage::log(ruleMessage);
|
||||
std::cout << modsecurity::RuleMessage::log(*ruleMessage);
|
||||
std::cout << std::endl;
|
||||
std::cout << " ** %d is meant to be informed by the webserver.";
|
||||
std::cout << std::endl;
|
||||
} else {
|
||||
std::cout << " * Match, but no disruptive action: ";
|
||||
std::cout << modsecurity::RuleMessage::log(ruleMessage);
|
||||
std::cout << modsecurity::RuleMessage::log(*ruleMessage);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -81,27 +81,15 @@ class Action {
|
||||
set_name_and_payload(_action);
|
||||
}
|
||||
|
||||
Action(const Action &a)
|
||||
: m_isNone(a.m_isNone),
|
||||
temporaryAction(a.temporaryAction),
|
||||
action_kind(a.action_kind),
|
||||
m_name(a.m_name),
|
||||
m_parser_payload(a.m_parser_payload) { }
|
||||
Action(const Action &a) = delete;
|
||||
|
||||
Action &operator=(const Action& a) {
|
||||
m_isNone = a.m_isNone;
|
||||
temporaryAction = a.temporaryAction;
|
||||
action_kind = a.action_kind;
|
||||
m_name = a.m_name;
|
||||
m_parser_payload = a.m_parser_payload;
|
||||
return *this;
|
||||
}
|
||||
Action &operator=(const Action& a) = delete;
|
||||
|
||||
virtual ~Action() { }
|
||||
|
||||
virtual bool evaluate(RuleWithActions *rule, Transaction *transaction);
|
||||
virtual bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> ruleMessage) {
|
||||
RuleMessage &ruleMessage) {
|
||||
return evaluate(rule, transaction);
|
||||
}
|
||||
virtual bool init(std::string *error) { return true; }
|
||||
@ -117,11 +105,11 @@ class Action {
|
||||
}
|
||||
|
||||
if (pos == std::string::npos) {
|
||||
m_name = std::shared_ptr<std::string>(new std::string(data));
|
||||
m_name = std::make_shared<std::string>(data);
|
||||
return;
|
||||
}
|
||||
|
||||
m_name = std::shared_ptr<std::string>(new std::string(data, 0, pos));
|
||||
m_name = std::make_shared<std::string>(data, 0, pos);
|
||||
m_parser_payload = std::string(data, pos + 1, data.length());
|
||||
|
||||
if (m_parser_payload.at(0) == '\'' && m_parser_payload.size() > 2) {
|
||||
|
@ -42,7 +42,7 @@ class AnchoredSetVariableTranslationProxy {
|
||||
: m_name(name),
|
||||
m_fount(fount)
|
||||
{
|
||||
m_translate = [](std::string *name, std::vector<const VariableValue *> *l) {
|
||||
m_translate = [](const std::string *name, std::vector<const VariableValue *> *l) {
|
||||
for (int i = 0; i < l->size(); ++i) {
|
||||
VariableValue *newVariableValue = new VariableValue(name, &l->at(i)->getKey(), &l->at(i)->getKey());
|
||||
const VariableValue *oldVariableValue = l->at(i);
|
||||
@ -100,13 +100,9 @@ class AnchoredSetVariableTranslationProxy {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<std::string> ret(new std::string(""));
|
||||
auto ret = std::make_unique<std::string>(l[0]->getValue());
|
||||
|
||||
ret->assign(l.at(0)->getValue());
|
||||
|
||||
while (!l.empty()) {
|
||||
auto &a = l.back();
|
||||
l.pop_back();
|
||||
for(auto a : l) {
|
||||
delete a;
|
||||
}
|
||||
|
||||
|
@ -153,17 +153,18 @@ class AuditLog {
|
||||
bool setStorageDirMode(int permission);
|
||||
bool setFileMode(int permission);
|
||||
bool setStatus(AuditLogStatus new_status);
|
||||
bool setRelevantStatus(const std::basic_string<char>& new_relevant_status);
|
||||
bool setFilePath1(const std::basic_string<char>& path);
|
||||
bool setFilePath2(const std::basic_string<char>& path);
|
||||
bool setStorageDir(const std::basic_string<char>& path);
|
||||
bool setRelevantStatus(std::string_view new_relevant_status);
|
||||
bool setFilePath1(std::string_view path);
|
||||
bool setFilePath2(std::string_view path);
|
||||
bool setStorageDir(std::string_view path);
|
||||
bool setPrefix(std::string_view prefix);
|
||||
bool setFormat(AuditLogFormat fmt);
|
||||
|
||||
int getDirectoryPermission() const;
|
||||
int getFilePermission() const;
|
||||
int getParts() const;
|
||||
|
||||
bool setParts(const std::basic_string<char>& new_parts);
|
||||
bool setParts(std::string_view new_parts);
|
||||
bool setType(AuditLogType audit_type);
|
||||
|
||||
bool init(std::string *error);
|
||||
@ -173,8 +174,8 @@ class AuditLog {
|
||||
bool saveIfRelevant(Transaction *transaction, int parts);
|
||||
bool isRelevant(int status);
|
||||
|
||||
static int addParts(int parts, const std::string& new_parts);
|
||||
static int removeParts(int parts, const std::string& new_parts);
|
||||
static int addParts(int parts, std::string_view new_parts);
|
||||
static int removeParts(int parts, std::string_view new_parts);
|
||||
|
||||
void setCtlAuditEngineActive() {
|
||||
m_ctlAuditEngineActive = true;
|
||||
@ -182,31 +183,32 @@ class AuditLog {
|
||||
|
||||
bool merge(AuditLog *from, std::string *error);
|
||||
|
||||
std::string m_path1;
|
||||
std::string m_path2;
|
||||
std::string m_storage_dir;
|
||||
std::string m_path1 = std::string("");
|
||||
std::string m_path2 = std::string("");
|
||||
std::string m_storage_dir = std::string("");
|
||||
std::string m_prefix = std::string("");
|
||||
|
||||
AuditLogFormat m_format;
|
||||
AuditLogFormat m_format = NotSetAuditLogFormat;
|
||||
|
||||
protected:
|
||||
int m_parts;
|
||||
int m_parts = -1;
|
||||
int m_defaultParts = AAuditLogPart | BAuditLogPart | CAuditLogPart
|
||||
| FAuditLogPart | HAuditLogPart | ZAuditLogPart;
|
||||
|
||||
int m_filePermission;
|
||||
int m_filePermission = -1;
|
||||
int m_defaultFilePermission = 0640;
|
||||
|
||||
int m_directoryPermission;
|
||||
int m_directoryPermission = -1;
|
||||
int m_defaultDirectoryPermission = 0750;
|
||||
|
||||
private:
|
||||
AuditLogStatus m_status;
|
||||
AuditLogStatus m_status = NotSetLogStatus;
|
||||
|
||||
AuditLogType m_type;
|
||||
std::string m_relevant;
|
||||
AuditLogType m_type = NotSetAuditLogType;
|
||||
std::string m_relevant = std::string("");
|
||||
|
||||
audit_log::writer::Writer *m_writer;
|
||||
bool m_ctlAuditEngineActive; // rules have at least one action On or RelevantOnly
|
||||
audit_log::writer::Writer *m_writer = nullptr;
|
||||
bool m_ctlAuditEngineActive = false; // rules have at least one action On or RelevantOnly
|
||||
};
|
||||
|
||||
|
||||
|
@ -190,7 +190,7 @@ namespace modsecurity {
|
||||
|
||||
#define MODSECURITY_MAJOR "3"
|
||||
#define MODSECURITY_MINOR "0"
|
||||
#define MODSECURITY_PATCHLEVEL "13"
|
||||
#define MODSECURITY_PATCHLEVEL "14"
|
||||
#define MODSECURITY_TAG ""
|
||||
#define MODSECURITY_TAG_NUM "100"
|
||||
|
||||
@ -198,7 +198,7 @@ namespace modsecurity {
|
||||
MODSECURITY_MINOR "." MODSECURITY_PATCHLEVEL \
|
||||
MODSECURITY_TAG
|
||||
|
||||
#define MODSECURITY_VERSION_NUM 30130100
|
||||
#define MODSECURITY_VERSION_NUM 30140100
|
||||
|
||||
#define MODSECURITY_CHECK_VERSION(a) (MODSECURITY_VERSION_NUM <= a)
|
||||
|
||||
@ -292,7 +292,7 @@ class ModSecurity {
|
||||
*/
|
||||
void setServerLogCb(ModSecLogCb cb, int properties);
|
||||
|
||||
void serverLog(void *data, std::shared_ptr<RuleMessage> rm);
|
||||
void serverLog(void *data, const RuleMessage &rm);
|
||||
|
||||
const std::string& getConnectorInformation() const;
|
||||
|
||||
|
@ -13,15 +13,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
#ifndef HEADERS_MODSECURITY_RULE_H_
|
||||
#define HEADERS_MODSECURITY_RULE_H_
|
||||
|
||||
@ -31,6 +22,12 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace modsecurity {
|
||||
namespace variables {
|
||||
class Variable;
|
||||
@ -67,33 +64,23 @@ using MatchActions = std::vector<actions::Action *>;
|
||||
|
||||
class Rule {
|
||||
public:
|
||||
Rule(std::unique_ptr<std::string> fileName, int lineNumber)
|
||||
: m_fileName(std::make_shared<std::string>(*fileName)),
|
||||
Rule(const std::string &fileName, int lineNumber)
|
||||
: m_fileName(fileName),
|
||||
m_lineNumber(lineNumber),
|
||||
m_phase(modsecurity::Phases::RequestHeadersPhase) {
|
||||
}
|
||||
|
||||
Rule(const Rule &other) :
|
||||
m_fileName(other.m_fileName),
|
||||
m_lineNumber(other.m_lineNumber),
|
||||
m_phase(other.m_phase)
|
||||
{ }
|
||||
Rule(const Rule &other) = delete;
|
||||
|
||||
Rule &operator=(const Rule& other) {
|
||||
m_fileName = other.m_fileName;
|
||||
m_lineNumber = other.m_lineNumber;
|
||||
m_phase = other.m_phase;
|
||||
return *this;
|
||||
}
|
||||
Rule &operator=(const Rule &other) = delete;
|
||||
|
||||
virtual ~Rule() {}
|
||||
|
||||
virtual bool evaluate(Transaction *transaction) = 0;
|
||||
|
||||
virtual bool evaluate(Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) = 0;
|
||||
virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) = 0;
|
||||
|
||||
std::shared_ptr<std::string> getFileName() const {
|
||||
const std::string& getFileName() const {
|
||||
return m_fileName;
|
||||
}
|
||||
|
||||
@ -105,18 +92,15 @@ class Rule {
|
||||
void setPhase(int phase) { m_phase = phase; }
|
||||
|
||||
virtual std::string getReference() {
|
||||
if (m_fileName) {
|
||||
return *m_fileName + ":" + std::to_string(m_lineNumber);
|
||||
}
|
||||
return "<<no file>>:" + std::to_string(m_lineNumber);
|
||||
return m_fileName + ":" + std::to_string(m_lineNumber);
|
||||
}
|
||||
|
||||
|
||||
virtual bool isMarker() { return false; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::string> m_fileName;
|
||||
int m_lineNumber;
|
||||
const std::string m_fileName;
|
||||
const int m_lineNumber;
|
||||
// FIXME: phase may not be neede to SecMarker.
|
||||
int m_phase;
|
||||
};
|
||||
|
@ -13,15 +13,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
#ifndef HEADERS_MODSECURITY_RULE_MARKER_H_
|
||||
#define HEADERS_MODSECURITY_RULE_MARKER_H_
|
||||
|
||||
@ -32,6 +23,9 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace modsecurity {
|
||||
|
||||
|
||||
@ -39,48 +33,34 @@ class RuleMarker : public Rule {
|
||||
public:
|
||||
RuleMarker(
|
||||
const std::string &name,
|
||||
std::unique_ptr<std::string> fileName,
|
||||
const std::string &fileName,
|
||||
int lineNumber)
|
||||
: Rule(std::move(fileName), lineNumber),
|
||||
m_name(std::make_shared<std::string>(name)) { }
|
||||
: Rule(fileName, lineNumber),
|
||||
m_name(name) { }
|
||||
|
||||
RuleMarker(const RuleMarker& r) :
|
||||
Rule(r),
|
||||
m_name(r.m_name)
|
||||
{ }
|
||||
RuleMarker(const RuleMarker &r) = delete;
|
||||
|
||||
RuleMarker &operator =(const RuleMarker& r) {
|
||||
Rule::operator = (r);
|
||||
m_name = r.m_name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual bool evaluate(Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override {
|
||||
RuleMarker &operator=(const RuleMarker &r) = delete;
|
||||
|
||||
virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override {
|
||||
return evaluate(transaction);
|
||||
}
|
||||
|
||||
virtual bool evaluate(Transaction *transaction) override {
|
||||
if (transaction->isInsideAMarker()) {
|
||||
if (*transaction->getCurrentMarker() == *m_name) {
|
||||
if (transaction->isInsideAMarker() &&
|
||||
*transaction->getCurrentMarker() == m_name) {
|
||||
transaction->removeMarker();
|
||||
// FIXME: Move this to .cc
|
||||
// ms_dbg_a(transaction, 4, "Out of a SecMarker " + *m_name);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
std::shared_ptr<std::string> getName() {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
bool isMarker() override { return true; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::string> m_name;
|
||||
const std::string m_name;
|
||||
};
|
||||
|
||||
|
||||
|
@ -13,14 +13,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
#ifndef HEADERS_MODSECURITY_RULE_MESSAGE_H_
|
||||
#define HEADERS_MODSECURITY_RULE_MESSAGE_H_
|
||||
|
||||
@ -31,8 +23,10 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace modsecurity {
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
namespace modsecurity {
|
||||
|
||||
|
||||
class RuleMessage {
|
||||
@ -42,173 +36,67 @@ class RuleMessage {
|
||||
ClientLogMessageInfo = 4
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* FIXME: RuleMessage is currently too big, doing a lot of
|
||||
* unnecessary data duplication. Needs to be shrink down.
|
||||
*
|
||||
*/
|
||||
RuleMessage(RuleWithActions *rule, Transaction *trans) :
|
||||
m_accuracy(rule->m_accuracy),
|
||||
m_clientIpAddress(trans->m_clientIpAddress),
|
||||
m_data(""),
|
||||
m_id(trans->m_id),
|
||||
m_isDisruptive(false),
|
||||
m_match(""),
|
||||
m_maturity(rule->m_maturity),
|
||||
m_message(""),
|
||||
m_noAuditLog(false),
|
||||
m_phase(rule->getPhase() - 1),
|
||||
m_reference(""),
|
||||
m_rev(rule->m_rev),
|
||||
RuleMessage(const RuleWithActions &rule, const Transaction &trans) :
|
||||
m_rule(rule),
|
||||
m_ruleFile(rule->getFileName()),
|
||||
m_ruleId(rule->m_ruleId),
|
||||
m_ruleLine(rule->getLineNumber()),
|
||||
m_saveMessage(true),
|
||||
m_serverIpAddress(trans->m_serverIpAddress),
|
||||
m_requestHostName(trans->m_requestHostName),
|
||||
m_severity(0),
|
||||
m_uriNoQueryStringDecoded(trans->m_uri_no_query_string_decoded),
|
||||
m_ver(rule->m_ver),
|
||||
m_tags()
|
||||
{ }
|
||||
|
||||
explicit RuleMessage(RuleMessage *rule) :
|
||||
m_accuracy(rule->m_accuracy),
|
||||
m_clientIpAddress(rule->m_clientIpAddress),
|
||||
m_data(rule->m_data),
|
||||
m_id(rule->m_id),
|
||||
m_isDisruptive(rule->m_isDisruptive),
|
||||
m_match(rule->m_match),
|
||||
m_maturity(rule->m_maturity),
|
||||
m_message(rule->m_message),
|
||||
m_noAuditLog(rule->m_noAuditLog),
|
||||
m_phase(rule->m_phase),
|
||||
m_reference(rule->m_reference),
|
||||
m_rev(rule->m_rev),
|
||||
m_rule(rule->m_rule),
|
||||
m_ruleFile(rule->m_ruleFile),
|
||||
m_ruleId(rule->m_ruleId),
|
||||
m_ruleLine(rule->m_ruleLine),
|
||||
m_saveMessage(rule->m_saveMessage),
|
||||
m_serverIpAddress(rule->m_serverIpAddress),
|
||||
m_requestHostName(rule->m_requestHostName),
|
||||
m_severity(rule->m_severity),
|
||||
m_uriNoQueryStringDecoded(rule->m_uriNoQueryStringDecoded),
|
||||
m_ver(rule->m_ver),
|
||||
m_tags(rule->m_tags)
|
||||
{ }
|
||||
|
||||
RuleMessage(const RuleMessage& ruleMessage)
|
||||
: m_accuracy(ruleMessage.m_accuracy),
|
||||
m_clientIpAddress(ruleMessage.m_clientIpAddress),
|
||||
m_data(ruleMessage.m_data),
|
||||
m_id(ruleMessage.m_id),
|
||||
m_isDisruptive(ruleMessage.m_isDisruptive),
|
||||
m_match(ruleMessage.m_match),
|
||||
m_maturity(ruleMessage.m_maturity),
|
||||
m_message(ruleMessage.m_message),
|
||||
m_noAuditLog(ruleMessage.m_noAuditLog),
|
||||
m_phase(ruleMessage.m_phase),
|
||||
m_reference(ruleMessage.m_reference),
|
||||
m_rev(ruleMessage.m_rev),
|
||||
m_rule(ruleMessage.m_rule),
|
||||
m_ruleFile(ruleMessage.m_ruleFile),
|
||||
m_ruleId(ruleMessage.m_ruleId),
|
||||
m_ruleLine(ruleMessage.m_ruleLine),
|
||||
m_saveMessage(ruleMessage.m_saveMessage),
|
||||
m_serverIpAddress(ruleMessage.m_serverIpAddress),
|
||||
m_requestHostName(ruleMessage.m_requestHostName),
|
||||
m_severity(ruleMessage.m_severity),
|
||||
m_uriNoQueryStringDecoded(ruleMessage.m_uriNoQueryStringDecoded),
|
||||
m_ver(ruleMessage.m_ver),
|
||||
m_tags(ruleMessage.m_tags)
|
||||
{ }
|
||||
|
||||
RuleMessage &operator=(const RuleMessage& ruleMessage) {
|
||||
m_accuracy = ruleMessage.m_accuracy;
|
||||
m_clientIpAddress = ruleMessage.m_clientIpAddress;
|
||||
m_data = ruleMessage.m_data;
|
||||
m_id = ruleMessage.m_id;
|
||||
m_isDisruptive = ruleMessage.m_isDisruptive;
|
||||
m_match = ruleMessage.m_match;
|
||||
m_maturity = ruleMessage.m_maturity;
|
||||
m_message = ruleMessage.m_message;
|
||||
m_noAuditLog = ruleMessage.m_noAuditLog;
|
||||
m_phase = ruleMessage.m_phase;
|
||||
m_reference = ruleMessage.m_reference;
|
||||
m_rev = ruleMessage.m_rev;
|
||||
m_rule = ruleMessage.m_rule;
|
||||
m_ruleFile = ruleMessage.m_ruleFile;
|
||||
m_ruleId = ruleMessage.m_ruleId;
|
||||
m_ruleLine = ruleMessage.m_ruleLine;
|
||||
m_saveMessage = ruleMessage.m_saveMessage;
|
||||
m_serverIpAddress = ruleMessage.m_serverIpAddress;
|
||||
m_requestHostName = ruleMessage.m_requestHostName;
|
||||
m_severity = ruleMessage.m_severity;
|
||||
m_uriNoQueryStringDecoded = ruleMessage.m_uriNoQueryStringDecoded;
|
||||
m_ver = ruleMessage.m_ver;
|
||||
m_tags = ruleMessage.m_tags;
|
||||
return *this;
|
||||
m_transaction(trans)
|
||||
{
|
||||
reset(true);
|
||||
}
|
||||
|
||||
void clean() {
|
||||
m_data = "";
|
||||
m_match = "";
|
||||
RuleMessage(const RuleMessage &ruleMessage) = default;
|
||||
RuleMessage &operator=(const RuleMessage &ruleMessage) = delete;
|
||||
|
||||
void reset(const bool resetSaveMessage)
|
||||
{
|
||||
m_data.clear();
|
||||
m_isDisruptive = false;
|
||||
m_reference = "";
|
||||
m_match.clear();
|
||||
m_message.clear();
|
||||
m_noAuditLog = false;
|
||||
m_reference.clear();
|
||||
if (resetSaveMessage == true)
|
||||
m_saveMessage = true;
|
||||
m_severity = 0;
|
||||
m_ver = "";
|
||||
m_tags.clear();
|
||||
}
|
||||
|
||||
std::string log() {
|
||||
return log(this, 0);
|
||||
std::string log() const {
|
||||
return log(*this, 0);
|
||||
}
|
||||
std::string log(int props) {
|
||||
return log(this, props);
|
||||
std::string log(int props) const {
|
||||
return log(*this, props);
|
||||
}
|
||||
std::string log(int props, int responseCode) {
|
||||
return log(this, props, responseCode);
|
||||
std::string log(int props, int responseCode) const {
|
||||
return log(*this, props, responseCode);
|
||||
}
|
||||
std::string errorLog() {
|
||||
return log(this,
|
||||
ClientLogMessageInfo | ErrorLogTailLogMessageInfo);
|
||||
std::string errorLog() const {
|
||||
return log(*this,
|
||||
ClientLogMessageInfo | ErrorLogTailLogMessageInfo);
|
||||
}
|
||||
|
||||
static std::string log(const RuleMessage *rm, int props, int code);
|
||||
static std::string log(const RuleMessage *rm, int props) {
|
||||
static std::string log(const RuleMessage &rm, int props, int code);
|
||||
static std::string log(const RuleMessage &rm, int props) {
|
||||
return log(rm, props, -1);
|
||||
}
|
||||
static std::string log(const RuleMessage *rm) {
|
||||
static std::string log(const RuleMessage &rm) {
|
||||
return log(rm, 0);
|
||||
}
|
||||
|
||||
static std::string _details(const RuleMessage *rm);
|
||||
static std::string _errorLogTail(const RuleMessage *rm);
|
||||
static std::string _details(const RuleMessage &rm);
|
||||
static std::string _errorLogTail(const RuleMessage &rm);
|
||||
|
||||
int m_accuracy;
|
||||
std::shared_ptr<std::string> m_clientIpAddress;
|
||||
int getPhase() const { return m_rule.getPhase() - 1; }
|
||||
|
||||
const RuleWithActions &m_rule;
|
||||
const Transaction &m_transaction;
|
||||
std::string m_data;
|
||||
std::shared_ptr<std::string> m_id;
|
||||
bool m_isDisruptive;
|
||||
bool m_isDisruptive = false;
|
||||
std::string m_match;
|
||||
int m_maturity;
|
||||
std::string m_message;
|
||||
bool m_noAuditLog;
|
||||
int m_phase;
|
||||
bool m_noAuditLog = false;
|
||||
std::string m_reference;
|
||||
std::string m_rev;
|
||||
RuleWithActions *m_rule;
|
||||
std::shared_ptr<std::string> m_ruleFile;
|
||||
int m_ruleId;
|
||||
int m_ruleLine;
|
||||
bool m_saveMessage;
|
||||
std::shared_ptr<std::string> m_serverIpAddress;
|
||||
std::shared_ptr<std::string> m_requestHostName;
|
||||
int m_severity;
|
||||
std::shared_ptr<std::string> m_uriNoQueryStringDecoded;
|
||||
std::string m_ver;
|
||||
bool m_saveMessage = true;
|
||||
int m_severity = 0;
|
||||
|
||||
std::list<std::string> m_tags;
|
||||
};
|
||||
|
@ -13,15 +13,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
#ifndef HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_
|
||||
#define HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_
|
||||
|
||||
@ -34,30 +25,18 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace modsecurity {
|
||||
|
||||
|
||||
class RuleUnconditional : public RuleWithActions {
|
||||
public:
|
||||
RuleUnconditional(
|
||||
std::vector<actions::Action *> *actions,
|
||||
Transformations *transformations,
|
||||
std::unique_ptr<std::string> fileName,
|
||||
int lineNumber)
|
||||
: RuleWithActions(actions, transformations, std::move(fileName), lineNumber) { }
|
||||
using RuleWithActions::RuleWithActions;
|
||||
|
||||
RuleUnconditional(const RuleUnconditional& r)
|
||||
: RuleWithActions(r)
|
||||
{ }
|
||||
|
||||
RuleUnconditional &operator=(const RuleUnconditional& r) {
|
||||
RuleWithActions::operator = (r);
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual bool evaluate(Transaction *transaction, std::shared_ptr<RuleMessage> ruleMessage) override;
|
||||
|
||||
private:
|
||||
virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -40,80 +40,32 @@ class RuleWithActions : public Rule {
|
||||
RuleWithActions(
|
||||
Actions *a,
|
||||
Transformations *t,
|
||||
std::unique_ptr<std::string> fileName,
|
||||
const std::string &fileName,
|
||||
int lineNumber);
|
||||
|
||||
~RuleWithActions();
|
||||
~RuleWithActions() override;
|
||||
|
||||
RuleWithActions(const RuleWithActions& r)
|
||||
: Rule(r),
|
||||
m_rev(r.m_rev),
|
||||
m_ver(r.m_ver),
|
||||
m_accuracy(r.m_accuracy),
|
||||
m_maturity(r.m_maturity),
|
||||
m_ruleId(r.m_ruleId),
|
||||
m_chainedRuleChild(r.m_chainedRuleChild),
|
||||
m_chainedRuleParent(r.m_chainedRuleParent),
|
||||
m_disruptiveAction(r.m_disruptiveAction),
|
||||
m_logData(r.m_logData),
|
||||
m_msg(r.m_msg),
|
||||
m_severity(r.m_severity),
|
||||
m_actionsRuntimePos(r.m_actionsRuntimePos),
|
||||
m_actionsSetVar(r.m_actionsSetVar),
|
||||
m_actionsTag(r.m_actionsTag),
|
||||
m_transformations(r.m_transformations),
|
||||
m_containsCaptureAction(r.m_containsCaptureAction),
|
||||
m_containsMultiMatchAction(r.m_containsMultiMatchAction),
|
||||
m_containsStaticBlockAction(r.m_containsStaticBlockAction),
|
||||
m_isChained(r.m_isChained)
|
||||
{ }
|
||||
RuleWithActions(const RuleWithActions &r) = delete;
|
||||
|
||||
RuleWithActions &operator=(const RuleWithActions& r) {
|
||||
Rule::operator = (r);
|
||||
m_rev = r.m_rev;
|
||||
m_ver = r.m_ver;
|
||||
m_accuracy = r.m_accuracy;
|
||||
m_maturity = r.m_maturity;
|
||||
m_ruleId = r.m_ruleId;
|
||||
m_chainedRuleChild = r.m_chainedRuleChild;
|
||||
m_chainedRuleParent = r.m_chainedRuleParent;
|
||||
|
||||
m_disruptiveAction = r.m_disruptiveAction;
|
||||
m_logData = r.m_logData;
|
||||
m_msg = r.m_msg;
|
||||
m_severity = r.m_severity;
|
||||
m_actionsRuntimePos = r.m_actionsRuntimePos;
|
||||
m_actionsSetVar = r.m_actionsSetVar;
|
||||
m_actionsTag = r.m_actionsTag;
|
||||
|
||||
m_transformations = r.m_transformations;
|
||||
|
||||
m_containsCaptureAction = r.m_containsCaptureAction;
|
||||
m_containsMultiMatchAction = r.m_containsMultiMatchAction;
|
||||
m_containsStaticBlockAction = r.m_containsStaticBlockAction;
|
||||
m_isChained = r.m_isChained;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual bool evaluate(Transaction *transaction, std::shared_ptr<RuleMessage> ruleMessage) override;
|
||||
RuleWithActions &operator=(const RuleWithActions &r) = delete;
|
||||
|
||||
virtual bool evaluate(Transaction *transaction) override;
|
||||
|
||||
virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
|
||||
void executeActionsIndependentOfChainedRuleResult(
|
||||
Transaction *trasn,
|
||||
bool *containsDisruptive,
|
||||
std::shared_ptr<RuleMessage> ruleMessage);
|
||||
RuleMessage &ruleMessage);
|
||||
|
||||
void executeActionsAfterFullMatch(
|
||||
Transaction *trasn,
|
||||
bool containsDisruptive,
|
||||
std::shared_ptr<RuleMessage> ruleMessage);
|
||||
RuleMessage &ruleMessage);
|
||||
|
||||
void executeAction(Transaction *trans,
|
||||
bool containsBlock,
|
||||
std::shared_ptr<RuleMessage> ruleMessage,
|
||||
RuleMessage &ruleMessage,
|
||||
actions::Action *a,
|
||||
bool context);
|
||||
|
||||
@ -122,12 +74,12 @@ class RuleWithActions : public Rule {
|
||||
const Transaction *trasn, const std::string &value, TransformationResults &ret);
|
||||
|
||||
void performLogging(Transaction *trans,
|
||||
std::shared_ptr<RuleMessage> ruleMessage,
|
||||
RuleMessage &ruleMessage,
|
||||
bool lastLog = true,
|
||||
bool chainedParentNull = false);
|
||||
bool chainedParentNull = false) const;
|
||||
|
||||
std::vector<actions::Action *> getActionsByName(const std::string& name,
|
||||
Transaction *t);
|
||||
const Transaction *t);
|
||||
bool containsTag(const std::string& name, Transaction *t);
|
||||
bool containsMsg(const std::string& name, Transaction *t);
|
||||
|
||||
|
@ -42,13 +42,12 @@ class RuleWithOperator : public RuleWithActions {
|
||||
variables::Variables *variables,
|
||||
std::vector<actions::Action *> *actions,
|
||||
Transformations *transformations,
|
||||
std::unique_ptr<std::string> fileName,
|
||||
const std::string &fileName,
|
||||
int lineNumber);
|
||||
|
||||
virtual ~RuleWithOperator();
|
||||
~RuleWithOperator() override;
|
||||
|
||||
bool evaluate(Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
|
||||
void getVariablesExceptions(Transaction &t,
|
||||
variables::Variables *exclusion, variables::Variables *addition);
|
||||
@ -56,14 +55,13 @@ class RuleWithOperator : public RuleWithActions {
|
||||
variables::Variables *eclusion, Transaction *trans);
|
||||
|
||||
bool executeOperatorAt(Transaction *trasn, const std::string &key,
|
||||
const std::string &value, std::shared_ptr<RuleMessage> rm);
|
||||
const std::string &value, RuleMessage &ruleMessage);
|
||||
|
||||
static void updateMatchedVars(Transaction *trasn, const std::string &key,
|
||||
const std::string &value);
|
||||
static void cleanMatchedVars(Transaction *trasn);
|
||||
|
||||
|
||||
std::string getOperatorName() const;
|
||||
const std::string& getOperatorName() const;
|
||||
|
||||
virtual std::string getReference() override {
|
||||
return std::to_string(m_ruleId);
|
||||
|
@ -41,16 +41,16 @@ namespace modsecurity {
|
||||
class Rules {
|
||||
public:
|
||||
void dump() const {
|
||||
for (int j = 0; j < m_rules.size(); j++) {
|
||||
std::cout << " Rule ID: " << m_rules.at(j)->getReference();
|
||||
std::cout << "--" << m_rules.at(j) << std::endl;
|
||||
for (const auto &r : m_rules) {
|
||||
std::cout << " Rule ID: " << r->getReference();
|
||||
std::cout << "--" << r << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int append(Rules *from, const std::vector<int64_t> &ids, std::ostringstream *err) {
|
||||
size_t j = 0;
|
||||
for (; j < from->size(); j++) {
|
||||
RuleWithOperator *rule = dynamic_cast<RuleWithOperator *>(from->at(j).get());
|
||||
const RuleWithOperator *rule = dynamic_cast<RuleWithOperator *>(from->at(j).get());
|
||||
if (rule && std::binary_search(ids.begin(), ids.end(), rule->m_ruleId)) {
|
||||
if (err != NULL) {
|
||||
*err << "Rule id: " << std::to_string(rule->m_ruleId) \
|
||||
@ -68,7 +68,7 @@ class Rules {
|
||||
}
|
||||
|
||||
bool insert(std::shared_ptr<Rule> rule, const std::vector<int64_t> *ids, std::ostringstream *err) {
|
||||
RuleWithOperator *r = dynamic_cast<RuleWithOperator *>(rule.get());
|
||||
const RuleWithOperator *r = dynamic_cast<RuleWithOperator *>(rule.get());
|
||||
if (r && ids != nullptr && std::binary_search(ids->begin(), ids->end(), r->m_ruleId)) {
|
||||
if (err != nullptr) {
|
||||
*err << "Rule id: " << std::to_string(r->m_ruleId) \
|
||||
|
@ -53,8 +53,8 @@ class RulesExceptions {
|
||||
bool contains(int a);
|
||||
bool merge(RulesExceptions *from);
|
||||
|
||||
bool loadRemoveRuleByMsg(const std::string &msg, std::string *error);
|
||||
bool loadRemoveRuleByTag(const std::string &msg, std::string *error);
|
||||
bool loadRemoveRuleByMsg(const std::string &msg, const std::string *error);
|
||||
bool loadRemoveRuleByTag(const std::string &msg, const std::string *error);
|
||||
|
||||
bool loadUpdateTargetByMsg(const std::string &msg,
|
||||
std::unique_ptr<std::vector<std::unique_ptr<variables::Variable> > > v,
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <cstdint>
|
||||
#endif
|
||||
|
||||
|
||||
@ -79,6 +80,8 @@ class RulesSet : public RulesSetProperties {
|
||||
void debug(int level, const std::string &id, const std::string &uri,
|
||||
const std::string &msg);
|
||||
|
||||
static void cleanMatchedVars(Transaction *trans);
|
||||
|
||||
RulesSetPhases m_rulesSetPhases;
|
||||
private:
|
||||
#ifndef NO_LOGS
|
||||
@ -93,7 +96,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
RulesSet *msc_create_rules_set(void);
|
||||
void msc_rules_dump(RulesSet *rules);
|
||||
void msc_rules_dump(const RulesSet *rules);
|
||||
int msc_rules_merge(RulesSet *rules_dst, RulesSet *rules_from, const char **error);
|
||||
int msc_rules_add_remote(RulesSet *rules, const char *key, const char *uri,
|
||||
const char **error);
|
||||
|
@ -13,6 +13,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <ctime>
|
||||
@ -22,6 +30,8 @@
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <cstdint>
|
||||
#endif
|
||||
|
||||
|
||||
@ -52,6 +62,11 @@
|
||||
to = (from == PropertyNotSetBodyLimitAction) ? default : from; \
|
||||
}
|
||||
|
||||
#define merge_xmlargparse_value(to, from, default) \
|
||||
if (to == PropertyNotSetConfigXMLParseXmlIntoArgs) { \
|
||||
to = (from == PropertyNotSetConfigXMLParseXmlIntoArgs) ? default : from; \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace modsecurity {
|
||||
@ -63,48 +78,134 @@ class Driver;
|
||||
using modsecurity::debug_log::DebugLog;
|
||||
using modsecurity::audit_log::AuditLog;
|
||||
|
||||
/** @ingroup ModSecurity_CPP_API */
|
||||
class ConfigInt {
|
||||
public:
|
||||
ConfigInt() : m_set(false), m_value(0) { }
|
||||
bool m_set;
|
||||
int m_value;
|
||||
// template for different numeric int types
|
||||
template <typename T>
|
||||
class ConfigValue {
|
||||
public:
|
||||
bool m_set = false;
|
||||
T m_value = 0;
|
||||
|
||||
void merge(ConfigInt *from) {
|
||||
if (m_set == true || from->m_set == false) {
|
||||
ConfigValue() = default;
|
||||
|
||||
void merge(const ConfigValue<T>* from) {
|
||||
if (m_set || !from->m_set) {
|
||||
return;
|
||||
}
|
||||
m_set = true;
|
||||
m_value = from->m_value;
|
||||
return;
|
||||
}
|
||||
|
||||
// default parser
|
||||
bool parse(const std::string& a, std::string* errmsg = nullptr) {
|
||||
|
||||
// use an alias type because the template can convert both signed and unsigned int
|
||||
using LimitSigned = std::conditional_t<std::is_signed_v<T>, std::int64_t, std::uint64_t>;
|
||||
LimitSigned val;
|
||||
|
||||
// clear errno variable, wee need that later
|
||||
errno = 0;
|
||||
|
||||
try {
|
||||
if constexpr (std::is_signed_v<T>) {
|
||||
val = static_cast<std::int64_t>(std::stoll(a));
|
||||
} else {
|
||||
val = static_cast<std::uint64_t>(std::stoull(a));
|
||||
}
|
||||
}
|
||||
catch (const std::invalid_argument&) {
|
||||
// probably can't occur, but we handle it anyway
|
||||
set_error(errmsg, "Invalid number format (not numeric)");
|
||||
return false;
|
||||
}
|
||||
catch (const std::out_of_range&) {
|
||||
// the value is out of range, we can not handle it
|
||||
set_error(errmsg, "Number out of range");
|
||||
return false;
|
||||
}
|
||||
catch (...) { // NOSONAR
|
||||
// we don't need to handle all exceptions, the engine's BISON parser
|
||||
// does not allow other symbols than numbers
|
||||
set_error(errmsg, "An unknown error occurred while parsing number.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
// The first condition will be true when the value is bigger than int64/uint64 maximum value.
|
||||
// The second condition checks whether the value fits into int64/uint64, but not
|
||||
// into the designed type, e.g., uint32; in that case the errno will be 0, but
|
||||
// we must check the value is not bigger than the defined maximum of the class.
|
||||
(errno == ERANGE && val == std::numeric_limits<LimitSigned>::max())
|
||||
||
|
||||
(val > static_cast<LimitSigned>(maxValue()))
|
||||
) {
|
||||
set_error(errmsg, "Value is too big.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
// same as above
|
||||
(errno == ERANGE && val == std::numeric_limits<LimitSigned>::min())
|
||||
||
|
||||
(val < static_cast<LimitSigned>(minValue()))
|
||||
) {
|
||||
set_error(errmsg, "Value is too small.");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_value = static_cast<T>(val);
|
||||
m_set = true;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
// derived classes must implement the maxValue
|
||||
virtual T maxValue() const = 0;
|
||||
// minValue is optional
|
||||
virtual T minValue() const { return 0; }
|
||||
|
||||
private:
|
||||
static inline void set_error(std::string* err, const char* msg) {
|
||||
if (err) {
|
||||
*err = msg;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** @ingroup ModSecurity_CPP_API */
|
||||
|
||||
class ConfigDouble {
|
||||
public:
|
||||
ConfigDouble() : m_set(false), m_value(0) { }
|
||||
bool m_set;
|
||||
double m_value;
|
||||
class ConfigInt : public ConfigValue<int32_t> {
|
||||
protected:
|
||||
int32_t minValue() const override {
|
||||
return std::numeric_limits<int32_t>::min();
|
||||
}
|
||||
int32_t maxValue() const override {
|
||||
return std::numeric_limits<int32_t>::max();
|
||||
}
|
||||
};
|
||||
|
||||
void merge(ConfigDouble *from) {
|
||||
if (m_set == true || from->m_set == false) {
|
||||
return;
|
||||
}
|
||||
m_set = true;
|
||||
m_value = from->m_value;
|
||||
return;
|
||||
class ConfigUnsignedInt : public ConfigValue<uint32_t> {
|
||||
protected:
|
||||
uint32_t maxValue() const override {
|
||||
return std::numeric_limits<uint32_t>::max();
|
||||
}
|
||||
};
|
||||
|
||||
class ConfigUnsignedLong : public ConfigValue<uint64_t> {
|
||||
protected:
|
||||
uint64_t maxValue() const override {
|
||||
return std::numeric_limits<uint64_t>::max();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ConfigString {
|
||||
public:
|
||||
ConfigString() : m_set(false), m_value("") { }
|
||||
bool m_set;
|
||||
std::string m_value;
|
||||
bool m_set = false;
|
||||
std::string m_value = "";
|
||||
ConfigString() = default;
|
||||
|
||||
void merge(ConfigString *from) {
|
||||
void merge(const ConfigString *from) {
|
||||
if (m_set == true || from->m_set == false) {
|
||||
return;
|
||||
}
|
||||
@ -117,10 +218,10 @@ class ConfigString {
|
||||
|
||||
class ConfigSet {
|
||||
public:
|
||||
ConfigSet() : m_set(false), m_clear(false) { }
|
||||
bool m_set;
|
||||
bool m_clear;
|
||||
bool m_set = false;
|
||||
bool m_clear = false;
|
||||
std::set<std::string> m_value;
|
||||
ConfigSet() = default;
|
||||
};
|
||||
|
||||
|
||||
@ -150,7 +251,7 @@ class ConfigUnicodeMap {
|
||||
static void loadConfig(std::string f, double codePage,
|
||||
RulesSetProperties *driver, std::string *errg);
|
||||
|
||||
void merge(ConfigUnicodeMap *from) {
|
||||
void merge(const ConfigUnicodeMap *from) {
|
||||
if (from->m_set == false) {
|
||||
return;
|
||||
}
|
||||
@ -177,6 +278,7 @@ class RulesSetProperties {
|
||||
m_secRequestBodyAccess(PropertyNotSetConfigBoolean),
|
||||
m_secResponseBodyAccess(PropertyNotSetConfigBoolean),
|
||||
m_secXMLExternalEntity(PropertyNotSetConfigBoolean),
|
||||
m_secXMLParseXmlIntoArgs(PropertyNotSetConfigXMLParseXmlIntoArgs),
|
||||
m_tmpSaveUploadedFiles(PropertyNotSetConfigBoolean),
|
||||
m_uploadKeepFiles(PropertyNotSetConfigBoolean),
|
||||
m_debugLog(new DebugLog()),
|
||||
@ -191,6 +293,7 @@ class RulesSetProperties {
|
||||
m_secRequestBodyAccess(PropertyNotSetConfigBoolean),
|
||||
m_secResponseBodyAccess(PropertyNotSetConfigBoolean),
|
||||
m_secXMLExternalEntity(PropertyNotSetConfigBoolean),
|
||||
m_secXMLParseXmlIntoArgs(PropertyNotSetConfigXMLParseXmlIntoArgs),
|
||||
m_tmpSaveUploadedFiles(PropertyNotSetConfigBoolean),
|
||||
m_uploadKeepFiles(PropertyNotSetConfigBoolean),
|
||||
m_debugLog(debugLog),
|
||||
@ -218,7 +321,8 @@ class RulesSetProperties {
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* The ConfigBoolean enumerator defines the states for configuration boolean values.
|
||||
* The default value is PropertyNotSetConfigBoolean.
|
||||
*/
|
||||
enum ConfigBoolean {
|
||||
TrueConfigBoolean,
|
||||
@ -226,6 +330,18 @@ class RulesSetProperties {
|
||||
PropertyNotSetConfigBoolean
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* The ConfigXMLParseXmlIntoArgs enumerator defines the states for the configuration
|
||||
* XMLParseXmlIntoArgs values.
|
||||
* The default value is PropertyNotSetConfigXMLParseXmlIntoArgs.
|
||||
*/
|
||||
enum ConfigXMLParseXmlIntoArgs {
|
||||
TrueConfigXMLParseXmlIntoArgs,
|
||||
FalseConfigXMLParseXmlIntoArgs,
|
||||
OnlyArgsConfigXMLParseXmlIntoArgs,
|
||||
PropertyNotSetConfigXMLParseXmlIntoArgs
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
@ -311,7 +427,7 @@ class RulesSetProperties {
|
||||
};
|
||||
|
||||
|
||||
static const char *ruleEngineStateString(RuleEngine i) {
|
||||
static std::string ruleEngineStateString(RuleEngine i) {
|
||||
switch (i) {
|
||||
case DisabledRuleEngine:
|
||||
return "Disabled";
|
||||
@ -322,7 +438,7 @@ class RulesSetProperties {
|
||||
case PropertyNotSetRuleEngine:
|
||||
return "PropertyNotSet/DetectionOnly";
|
||||
}
|
||||
return NULL;
|
||||
return std::string{};
|
||||
}
|
||||
|
||||
|
||||
@ -338,6 +454,19 @@ class RulesSetProperties {
|
||||
}
|
||||
}
|
||||
|
||||
static std::string configXMLParseXmlIntoArgsString(ConfigXMLParseXmlIntoArgs i) {
|
||||
switch (i) {
|
||||
case TrueConfigXMLParseXmlIntoArgs:
|
||||
return "True";
|
||||
case FalseConfigXMLParseXmlIntoArgs:
|
||||
return "False";
|
||||
case OnlyArgsConfigXMLParseXmlIntoArgs:
|
||||
return "OnlyArgs";
|
||||
case PropertyNotSetConfigXMLParseXmlIntoArgs:
|
||||
default:
|
||||
return "Not set";
|
||||
}
|
||||
}
|
||||
|
||||
static int mergeProperties(RulesSetProperties *from,
|
||||
RulesSetProperties *to, std::ostringstream *err) {
|
||||
@ -357,6 +486,10 @@ class RulesSetProperties {
|
||||
from->m_secXMLExternalEntity,
|
||||
PropertyNotSetConfigBoolean);
|
||||
|
||||
merge_xmlargparse_value(to->m_secXMLParseXmlIntoArgs,
|
||||
from->m_secXMLParseXmlIntoArgs,
|
||||
PropertyNotSetConfigXMLParseXmlIntoArgs);
|
||||
|
||||
merge_boolean_value(to->m_uploadKeepFiles,
|
||||
from->m_uploadKeepFiles,
|
||||
PropertyNotSetConfigBoolean);
|
||||
@ -464,16 +597,17 @@ class RulesSetProperties {
|
||||
ConfigBoolean m_secRequestBodyAccess;
|
||||
ConfigBoolean m_secResponseBodyAccess;
|
||||
ConfigBoolean m_secXMLExternalEntity;
|
||||
ConfigXMLParseXmlIntoArgs m_secXMLParseXmlIntoArgs;
|
||||
ConfigBoolean m_tmpSaveUploadedFiles;
|
||||
ConfigBoolean m_uploadKeepFiles;
|
||||
ConfigDouble m_argumentsLimit;
|
||||
ConfigDouble m_requestBodyJsonDepthLimit;
|
||||
ConfigDouble m_requestBodyLimit;
|
||||
ConfigDouble m_requestBodyNoFilesLimit;
|
||||
ConfigDouble m_responseBodyLimit;
|
||||
ConfigInt m_pcreMatchLimit;
|
||||
ConfigInt m_uploadFileLimit;
|
||||
ConfigInt m_uploadFileMode;
|
||||
ConfigUnsignedInt m_argumentsLimit;
|
||||
ConfigUnsignedInt m_requestBodyJsonDepthLimit;
|
||||
ConfigUnsignedLong m_requestBodyLimit;
|
||||
ConfigUnsignedLong m_requestBodyNoFilesLimit;
|
||||
ConfigUnsignedLong m_responseBodyLimit;
|
||||
ConfigUnsignedInt m_pcreMatchLimit;
|
||||
ConfigUnsignedInt m_uploadFileLimit;
|
||||
ConfigUnsignedInt m_uploadFileMode;
|
||||
DebugLog *m_debugLog;
|
||||
OnFailedRemoteRulesAction m_remoteRulesActionOnFailed;
|
||||
RuleEngine m_secRuleEngine;
|
||||
|
@ -13,6 +13,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HEADERS_MODSECURITY_TRANSACTION_H_
|
||||
#define HEADERS_MODSECURITY_TRANSACTION_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cassert>
|
||||
#include <ctime>
|
||||
@ -33,9 +36,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef HEADERS_MODSECURITY_TRANSACTION_H_
|
||||
#define HEADERS_MODSECURITY_TRANSACTION_H_
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef struct ModSecurity_t ModSecurity;
|
||||
typedef struct Transaction_t Transaction;
|
||||
@ -57,7 +57,7 @@ typedef struct Rules_t RulesSet;
|
||||
#define ms_dbg(b, c) \
|
||||
do { \
|
||||
if (m_rules && m_rules->m_debugLog && m_rules->m_debugLog->m_debugLevel >= b) { \
|
||||
m_rules->debug(b, *m_id.get(), m_uri, c); \
|
||||
m_rules->debug(b, m_id, m_uri, c); \
|
||||
} \
|
||||
} while (0);
|
||||
#else
|
||||
@ -80,15 +80,14 @@ typedef struct Rules_t RulesSet;
|
||||
|
||||
#define LOGFY_ADD(a, b) \
|
||||
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(a), strlen(a)); \
|
||||
if (b == NULL) { \
|
||||
if (b.data() == NULL) { \
|
||||
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(""), \
|
||||
strlen("")); \
|
||||
} else { \
|
||||
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(b), \
|
||||
strlen(b)); \
|
||||
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(b.data()), \
|
||||
b.length()); \
|
||||
}
|
||||
|
||||
|
||||
#define LOGFY_ADD_INT(a, b) \
|
||||
yajl_gen_string(g, reinterpret_cast<const unsigned char*>(a), strlen(a)); \
|
||||
yajl_gen_number(g, reinterpret_cast<const char*>(b), strlen(b));
|
||||
@ -327,8 +326,8 @@ class TransactionSecMarkerManagement {
|
||||
/** @ingroup ModSecurity_CPP_API */
|
||||
class Transaction : public TransactionAnchoredVariables, public TransactionSecMarkerManagement {
|
||||
public:
|
||||
Transaction(ModSecurity *transaction, RulesSet *rules, void *logCbData);
|
||||
Transaction(ModSecurity *transaction, RulesSet *rules, char *id,
|
||||
Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData);
|
||||
Transaction(ModSecurity *ms, RulesSet *rules, const char *id,
|
||||
void *logCbData);
|
||||
~Transaction();
|
||||
|
||||
@ -405,14 +404,14 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
size_t getRequestBodyLength();
|
||||
|
||||
#ifndef NO_LOGS
|
||||
void debug(int, const std::string &) const; // cppcheck-suppress functionStatic
|
||||
void debug(int, const std::string &) const;
|
||||
#endif
|
||||
void serverLog(std::shared_ptr<RuleMessage> rm);
|
||||
void serverLog(const RuleMessage &rm);
|
||||
|
||||
int getRuleEngineState() const;
|
||||
|
||||
std::string toJSON(int parts);
|
||||
std::string toOldAuditLogFormat(int parts, const std::string &trailer);
|
||||
std::string toOldAuditLogFormat(int parts, const std::string &trailer, const std::string &header);
|
||||
std::string toOldAuditLogFormatIndex(const std::string &filename,
|
||||
double size, const std::string &md5);
|
||||
|
||||
@ -426,12 +425,12 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
* need to be filled if there is no rule using the variable
|
||||
* `duration'.
|
||||
*/
|
||||
clock_t m_creationTimeStamp;
|
||||
const clock_t m_creationTimeStamp;
|
||||
|
||||
/**
|
||||
* Holds the client IP address.
|
||||
*/
|
||||
std::shared_ptr<std::string> m_clientIpAddress;
|
||||
std::string m_clientIpAddress;
|
||||
|
||||
/**
|
||||
* Holds the HTTP version: 1.2, 2.0, 3.0 and so on....
|
||||
@ -441,12 +440,12 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
/**
|
||||
* Holds the server IP Address
|
||||
*/
|
||||
std::shared_ptr<std::string> m_serverIpAddress;
|
||||
std::string m_serverIpAddress;
|
||||
|
||||
/**
|
||||
* Holds the request's hostname
|
||||
*/
|
||||
std::shared_ptr<std::string> m_requestHostName;
|
||||
std::string m_requestHostName;
|
||||
|
||||
/**
|
||||
* Holds the raw URI that was requested.
|
||||
@ -456,7 +455,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
/**
|
||||
* Holds the URI that was requests (without the query string).
|
||||
*/
|
||||
std::shared_ptr<std::string> m_uri_no_query_string_decoded;
|
||||
std::string m_uri_no_query_string_decoded;
|
||||
|
||||
/**
|
||||
* Holds the combined size of all arguments, later used to fill the
|
||||
@ -505,7 +504,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
/**
|
||||
* Rules object utilized during this specific transaction.
|
||||
*/
|
||||
RulesSet *m_rules;
|
||||
RulesSet * const m_rules;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -568,7 +567,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
* Contains the unique ID of the transaction. Use by the variable
|
||||
* `UNIQUE_ID'. This unique id is also saved as part of the AuditLog.
|
||||
*/
|
||||
std::shared_ptr<std::string> m_id;
|
||||
const std::string m_id;
|
||||
|
||||
/**
|
||||
* Holds the amount of rules that should be skipped. If bigger than 0 the
|
||||
@ -600,7 +599,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
* TODO: m_timeStamp and m_creationTimeStamp may be merged into a single
|
||||
* variable.
|
||||
*/
|
||||
time_t m_timeStamp;
|
||||
const time_t m_timeStamp;
|
||||
|
||||
|
||||
/**
|
||||
@ -619,6 +618,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
RequestBodyProcessor::JSON *m_json;
|
||||
|
||||
int m_secRuleEngine;
|
||||
int m_secXMLParseXmlIntoArgs;
|
||||
|
||||
std::string m_variableDuration;
|
||||
std::map<std::string, std::string> m_variableEnvs;
|
||||
@ -636,6 +636,10 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa
|
||||
std::vector<std::shared_ptr<RequestBodyProcessor::MultipartPartTmpFile>> m_multipartPartTmpFiles;
|
||||
|
||||
private:
|
||||
|
||||
Transaction(ModSecurity *ms, RulesSet *rules, const char *id,
|
||||
void *logCbData, const time_t timestamp);
|
||||
|
||||
/**
|
||||
* Pointer to the callback function that will be called to fill
|
||||
* the web server (connector) log.
|
||||
@ -656,7 +660,7 @@ Transaction *msc_new_transaction(ModSecurity *ms,
|
||||
|
||||
/** @ingroup ModSecurity_C_API */
|
||||
Transaction *msc_new_transaction_with_id(ModSecurity *ms,
|
||||
RulesSet *rules, char *id, void *logCbData);
|
||||
RulesSet *rules, const char *id, void *logCbData);
|
||||
|
||||
/** @ingroup ModSecurity_C_API */
|
||||
int msc_process_connection(Transaction *transaction,
|
||||
@ -709,7 +713,7 @@ int msc_process_uri(Transaction *transaction, const char *uri,
|
||||
const char *protocol, const char *http_version);
|
||||
|
||||
/** @ingroup ModSecurity_C_API */
|
||||
const char *msc_get_response_body(Transaction *transaction);
|
||||
const char *msc_get_response_body(const Transaction *transaction);
|
||||
|
||||
/** @ingroup ModSecurity_C_API */
|
||||
size_t msc_get_response_body_length(Transaction *transaction);
|
||||
|
@ -156,7 +156,7 @@ SecPcreMatchLimitRecursion 1000
|
||||
# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
|
||||
#
|
||||
SecRule TX:/^MSC_/ "!@streq 0" \
|
||||
"id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
|
||||
"id:'200005',phase:2,t:none,log,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
|
||||
|
||||
|
||||
# -- Response body handling --------------------------------------------------
|
||||
|
@ -28,6 +28,6 @@ libmbedtls_la_SOURCES = \
|
||||
mbedtls/library/sha1.c \
|
||||
mbedtls/library/platform_util.c
|
||||
|
||||
libmbedtls_la_CFLAGS = -DMBEDTLS_CONFIG_FILE=\"mbedtls/mbedtls_config.h\" -Imbedtls/include
|
||||
libmbedtls_la_CFLAGS = -DMBEDTLS_CONFIG_FILE=\"mbedtls/mbedtls_config.h\" -I$(top_srcdir)/others/mbedtls/include
|
||||
libmbedtls_la_CPPFLAGS =
|
||||
libmbedtls_la_LIBADD =
|
||||
|
BIN
others/modsec_white_bg.png
Executable file
BIN
others/modsec_white_bg.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
@ -68,21 +68,21 @@ libmodsecurity_includesub_actions_HEADERS = \
|
||||
|
||||
|
||||
noinst_HEADERS = \
|
||||
actions/*.h \
|
||||
actions/ctl/*.h \
|
||||
actions/data/*.h \
|
||||
actions/disruptive/*.h \
|
||||
actions/transformations/*.h \
|
||||
debug_log/*.h \
|
||||
audit_log/writer/*.h \
|
||||
collection/backend/*.h \
|
||||
operators/*.h \
|
||||
parser/*.h \
|
||||
request_body_processor/*.h \
|
||||
utils/*.h \
|
||||
variables/*.h \
|
||||
engine/*.h \
|
||||
*.h
|
||||
$(wildcard actions/*.h) \
|
||||
$(wildcard actions/ctl/*.h) \
|
||||
$(wildcard actions/data/*.h) \
|
||||
$(wildcard actions/disruptive/*.h) \
|
||||
$(wildcard actions/transformations/*.h) \
|
||||
$(wildcard debug_log/*.h) \
|
||||
$(wildcard audit_log/writer/*.h) \
|
||||
$(wildcard collection/backend/*.h) \
|
||||
$(wildcard operators/*.h) \
|
||||
$(wildcard parser/*.h) \
|
||||
$(wildcard request_body_processor/*.h) \
|
||||
$(wildcard utils/*.h) \
|
||||
$(wildcard variables/*.h) \
|
||||
$(wildcard engine/*.h) \
|
||||
$(wildcard *.h)
|
||||
|
||||
|
||||
ENGINES = \
|
||||
@ -119,6 +119,7 @@ ACTIONS = \
|
||||
actions/chain.cc \
|
||||
actions/ctl/audit_log_parts.cc \
|
||||
actions/ctl/audit_engine.cc \
|
||||
actions/ctl/parse_xml_into_args.cc \
|
||||
actions/ctl/rule_engine.cc \
|
||||
actions/ctl/request_body_processor_json.cc \
|
||||
actions/ctl/request_body_processor_xml.cc \
|
||||
@ -307,13 +308,14 @@ libmodsecurity_la_CFLAGS =
|
||||
|
||||
|
||||
libmodsecurity_la_CPPFLAGS = \
|
||||
-I.. \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_builddir) \
|
||||
-g \
|
||||
-I../others \
|
||||
-I../others/mbedtls/include \
|
||||
-I$(top_srcdir)/others \
|
||||
-I$(top_srcdir)/others/mbedtls/include \
|
||||
-fPIC \
|
||||
-O3 \
|
||||
-I../headers \
|
||||
-I$(top_srcdir)/headers \
|
||||
$(CURL_CFLAGS) \
|
||||
$(GEOIP_CFLAGS) \
|
||||
$(GLOBAL_CPPFLAGS) \
|
||||
|
@ -27,11 +27,10 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool AuditLog::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
rm->m_noAuditLog = false;
|
||||
bool AuditLog::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {
|
||||
ruleMessage.m_noAuditLog = false;
|
||||
ms_dbg_a(transaction, 9, "Saving transaction to logs");
|
||||
rm->m_saveMessage = true;
|
||||
ruleMessage.m_saveMessage = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -35,8 +35,7 @@ class AuditLog : public Action {
|
||||
explicit AuditLog(const std::string &action)
|
||||
: Action(action) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -29,15 +29,14 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool Block::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
bool Block::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {
|
||||
ms_dbg_a(transaction, 8, "Marking request as disruptive.");
|
||||
|
||||
for (auto &a : transaction->m_rules->m_defaultActions[rule->getPhase()]) {
|
||||
if (a->isDisruptive() == false) {
|
||||
continue;
|
||||
}
|
||||
a->evaluate(rule, transaction, rm);
|
||||
a->evaluate(rule, transaction, ruleMessage);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -35,8 +35,7 @@ class Block : public Action {
|
||||
public:
|
||||
explicit Block(const std::string &action) : Action(action) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
};
|
||||
|
||||
|
||||
|
63
src/actions/ctl/parse_xml_into_args.cc
Normal file
63
src/actions/ctl/parse_xml_into_args.cc
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2025 OWASP ModSecurity project
|
||||
*
|
||||
* 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 OWASP.
|
||||
* directly using the email address modsecurity@owasp.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "src/actions/ctl/parse_xml_into_args.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "modsecurity/rules_set_properties.h"
|
||||
#include "modsecurity/rules_set.h"
|
||||
#include "modsecurity/transaction.h"
|
||||
|
||||
namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace ctl {
|
||||
|
||||
|
||||
bool ParseXmlIntoArgs::init(std::string *error) {
|
||||
std::string what(m_parser_payload, 17, m_parser_payload.size() - 17);
|
||||
|
||||
if (what == "on") {
|
||||
m_secXMLParseXmlIntoArgs = RulesSetProperties::TrueConfigXMLParseXmlIntoArgs;
|
||||
} else if (what == "off") {
|
||||
m_secXMLParseXmlIntoArgs = RulesSetProperties::FalseConfigXMLParseXmlIntoArgs;
|
||||
} else if (what == "onlyargs") {
|
||||
m_secXMLParseXmlIntoArgs = RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs;
|
||||
} else {
|
||||
error->assign("Internal error. Expected: On, Off or OnlyArgs; " \
|
||||
"got: " + m_parser_payload);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseXmlIntoArgs::evaluate(RuleWithActions *rule, Transaction *transaction) {
|
||||
std::stringstream a;
|
||||
a << "Setting SecParseXmlIntoArgs to ";
|
||||
a << modsecurity::RulesSetProperties::configXMLParseXmlIntoArgsString(m_secXMLParseXmlIntoArgs);
|
||||
a << " as requested by a ctl:parseXmlIntoArgs action";
|
||||
|
||||
ms_dbg_a(transaction, 8, a.str());
|
||||
|
||||
transaction->m_secXMLParseXmlIntoArgs = m_secXMLParseXmlIntoArgs;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ctl
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
48
src/actions/ctl/parse_xml_into_args.h
Normal file
48
src/actions/ctl/parse_xml_into_args.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2025 OWASP ModSecurity Project
|
||||
*
|
||||
* 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 OWASP.
|
||||
* directly using the email address modsecurity@owasp.org
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "modsecurity/rules_set_properties.h"
|
||||
#include "modsecurity/actions/action.h"
|
||||
#include "modsecurity/transaction.h"
|
||||
|
||||
|
||||
#ifndef SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_
|
||||
#define SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_
|
||||
|
||||
namespace modsecurity {
|
||||
namespace actions {
|
||||
namespace ctl {
|
||||
|
||||
|
||||
class ParseXmlIntoArgs : public Action {
|
||||
public:
|
||||
explicit ParseXmlIntoArgs(const std::string &action)
|
||||
: Action(action),
|
||||
m_secXMLParseXmlIntoArgs(RulesSetProperties::PropertyNotSetConfigXMLParseXmlIntoArgs) { }
|
||||
|
||||
bool init(std::string *error) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
|
||||
|
||||
RulesSetProperties::ConfigXMLParseXmlIntoArgs m_secXMLParseXmlIntoArgs;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ctl
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
||||
|
||||
#endif // SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_
|
@ -84,10 +84,10 @@ bool RuleRemoveById::init(std::string *error) {
|
||||
}
|
||||
|
||||
bool RuleRemoveById::evaluate(RuleWithActions *rule, Transaction *transaction) {
|
||||
for (auto &i : m_ids) {
|
||||
for (const auto &i : m_ids) {
|
||||
transaction->m_ruleRemoveById.push_back(i);
|
||||
}
|
||||
for (auto &i : m_ranges) {
|
||||
for (const auto &i : m_ranges) {
|
||||
transaction->m_ruleRemoveByIdRange.push_back(i);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ bool Status::init(std::string *error) {
|
||||
|
||||
|
||||
bool Status::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
RuleMessage &ruleMessage) {
|
||||
transaction->m_it.status = m_status;
|
||||
return true;
|
||||
}
|
||||
|
@ -37,8 +37,7 @@ class Status : public Action {
|
||||
: Action(action), m_status(0) { }
|
||||
|
||||
bool init(std::string *error) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
|
||||
int m_status;
|
||||
};
|
||||
|
@ -29,7 +29,7 @@ namespace disruptive {
|
||||
|
||||
|
||||
bool Deny::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
RuleMessage &ruleMessage) {
|
||||
ms_dbg_a(transaction, 8, "Running action deny");
|
||||
|
||||
if (transaction->m_it.status == 200) {
|
||||
@ -38,9 +38,9 @@ bool Deny::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
|
||||
transaction->m_it.disruptive = true;
|
||||
intervention::freeLog(&transaction->m_it);
|
||||
rm->m_isDisruptive = true;
|
||||
ruleMessage.m_isDisruptive = true;
|
||||
transaction->m_it.log = strdup(
|
||||
rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
|
||||
ruleMessage.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -33,8 +33,7 @@ class Deny : public Action {
|
||||
public:
|
||||
explicit Deny(const std::string &action) : Action(action) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
bool isDisruptive() override { return true; }
|
||||
};
|
||||
|
||||
|
@ -33,7 +33,7 @@ namespace disruptive {
|
||||
|
||||
|
||||
bool Drop::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
RuleMessage &ruleMessage) {
|
||||
ms_dbg_a(transaction, 8, "Running action drop " \
|
||||
"[executing deny instead of drop.]");
|
||||
|
||||
@ -43,9 +43,9 @@ bool Drop::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
|
||||
transaction->m_it.disruptive = true;
|
||||
intervention::freeLog(&transaction->m_it);
|
||||
rm->m_isDisruptive = true;
|
||||
ruleMessage.m_isDisruptive = true;
|
||||
transaction->m_it.log = strdup(
|
||||
rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
|
||||
ruleMessage.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -32,8 +32,7 @@ class Drop : public Action {
|
||||
public:
|
||||
explicit Drop(const std::string &action) : Action(action) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
bool isDisruptive() override { return true; }
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,7 @@ namespace disruptive {
|
||||
|
||||
|
||||
bool Pass::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
RuleMessage &ruleMessage) {
|
||||
intervention::free(&transaction->m_it);
|
||||
intervention::reset(&transaction->m_it);
|
||||
|
||||
|
@ -31,8 +31,7 @@ class Pass : public Action {
|
||||
public:
|
||||
explicit Pass(const std::string &action) : Action(action) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
bool isDisruptive() override { return true; }
|
||||
};
|
||||
|
||||
|
@ -35,7 +35,7 @@ bool Redirect::init(std::string *error) {
|
||||
|
||||
|
||||
bool Redirect::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
RuleMessage &ruleMessage) {
|
||||
std::string m_urlExpanded(m_string->evaluate(transaction));
|
||||
/* if it was changed before, lets keep it. */
|
||||
if (transaction->m_it.status == 200
|
||||
@ -47,9 +47,9 @@ bool Redirect::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
transaction->m_it.url = strdup(m_urlExpanded.c_str());
|
||||
transaction->m_it.disruptive = true;
|
||||
intervention::freeLog(&transaction->m_it);
|
||||
rm->m_isDisruptive = true;
|
||||
ruleMessage.m_isDisruptive = true;
|
||||
transaction->m_it.log = strdup(
|
||||
rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
|
||||
ruleMessage.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -46,8 +46,7 @@ class Redirect : public Action {
|
||||
m_status(0),
|
||||
m_string(std::move(z)) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
bool init(std::string *error) override;
|
||||
bool isDisruptive() override { return true; }
|
||||
|
||||
|
@ -31,10 +31,7 @@ namespace actions {
|
||||
class Exec : public Action {
|
||||
public:
|
||||
explicit Exec(const std::string &action)
|
||||
: Action(action),
|
||||
m_script("") { }
|
||||
|
||||
~Exec() { }
|
||||
: Action(action) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
|
||||
bool init(std::string *error) override;
|
||||
|
@ -32,11 +32,6 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool ExpireVar::init(std::string *error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ExpireVar::evaluate(RuleWithActions *rule, Transaction *t) {
|
||||
|
||||
std::string expireExpressionExpanded(m_string->evaluate(t));
|
||||
@ -65,23 +60,23 @@ bool ExpireVar::evaluate(RuleWithActions *rule, Transaction *t) {
|
||||
|
||||
std::string collection = fully_qualified_var.substr(0, posDot);
|
||||
std::string variable_name = fully_qualified_var.substr(posDot+1);
|
||||
std::unique_ptr<RunTimeString> runTimeString(new RunTimeString());
|
||||
auto runTimeString = std::make_unique<RunTimeString>();
|
||||
runTimeString->appendText(fully_qualified_var);
|
||||
|
||||
if (collection == "ip") {
|
||||
std::unique_ptr<modsecurity::variables::Ip_DynamicElement> ip_dynamicElement(new modsecurity::variables::Ip_DynamicElement(std::move(runTimeString)));
|
||||
auto ip_dynamicElement = std::make_unique<modsecurity::variables::Ip_DynamicElement>(std::move(runTimeString));
|
||||
ip_dynamicElement->setExpiry(t, variable_name, expirySeconds);
|
||||
} else if (collection == "global") {
|
||||
std::unique_ptr<modsecurity::variables::Global_DynamicElement> global_dynamicElement(new modsecurity::variables::Global_DynamicElement(std::move(runTimeString)));
|
||||
auto global_dynamicElement = std::make_unique<modsecurity::variables::Global_DynamicElement>(std::move(runTimeString));
|
||||
global_dynamicElement->setExpiry(t, variable_name, expirySeconds);
|
||||
} else if (collection == "resource") {
|
||||
std::unique_ptr<modsecurity::variables::Resource_DynamicElement> resource_dynamicElement(new modsecurity::variables::Resource_DynamicElement(std::move(runTimeString)));
|
||||
auto resource_dynamicElement = std::make_unique<modsecurity::variables::Resource_DynamicElement>(std::move(runTimeString));
|
||||
resource_dynamicElement->setExpiry(t, variable_name, expirySeconds);
|
||||
} else if (collection == "session") {
|
||||
std::unique_ptr<modsecurity::variables::Session_DynamicElement> session_dynamicElement(new modsecurity::variables::Session_DynamicElement(std::move(runTimeString)));
|
||||
auto session_dynamicElement = std::make_unique<modsecurity::variables::Session_DynamicElement>(std::move(runTimeString));
|
||||
session_dynamicElement->setExpiry(t, variable_name, expirySeconds);
|
||||
} else if (collection == "user") {
|
||||
std::unique_ptr<modsecurity::variables::User_DynamicElement> user_dynamicElement(new modsecurity::variables::User_DynamicElement(std::move(runTimeString)));
|
||||
auto user_dynamicElement = std::make_unique<modsecurity::variables::User_DynamicElement>(std::move(runTimeString));
|
||||
user_dynamicElement->setExpiry(t, variable_name, expirySeconds);
|
||||
} else {
|
||||
ms_dbg_a(t, 5, "Invalid collection found in expirevar expression: collection must be `ip', `global', `resource', `user' or `session'");
|
||||
|
@ -40,7 +40,6 @@ class ExpireVar : public Action {
|
||||
m_string(std::move(z)) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
|
||||
bool init(std::string *error) override;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -28,10 +28,9 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool Log::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
bool Log::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {
|
||||
ms_dbg_a(transaction, 9, "Saving transaction to logs");
|
||||
rm->m_saveMessage = true;
|
||||
ruleMessage.m_saveMessage = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,7 @@ class Log : public Action {
|
||||
explicit Log(const std::string &action)
|
||||
: Action(action) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
};
|
||||
|
||||
} // namespace actions
|
||||
|
@ -29,9 +29,8 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool LogData::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
rm->m_data = data(transaction);
|
||||
bool LogData::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {
|
||||
ruleMessage.m_data = data(transaction);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -39,8 +39,7 @@ class LogData : public Action {
|
||||
: Action("logdata"),
|
||||
m_string(std::move(z)) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
|
||||
std::string data(Transaction *Transaction);
|
||||
|
||||
|
@ -46,10 +46,9 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool Msg::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
std::string msg = data(transaction);
|
||||
rm->m_message = msg;
|
||||
bool Msg::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {
|
||||
const auto msg = data(transaction);
|
||||
ruleMessage.m_message = msg;
|
||||
ms_dbg_a(transaction, 9, "Saving msg: " + msg);
|
||||
|
||||
return true;
|
||||
|
@ -40,8 +40,7 @@ class Msg : public Action {
|
||||
: Action("msg"),
|
||||
m_string(std::move(z)) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
|
||||
std::string data(Transaction *Transaction);
|
||||
std::unique_ptr<RunTimeString> m_string;
|
||||
|
@ -26,10 +26,9 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool NoAuditLog::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
rm->m_noAuditLog = true;
|
||||
rm->m_saveMessage = false;
|
||||
bool NoAuditLog::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {
|
||||
ruleMessage.m_noAuditLog = true;
|
||||
ruleMessage.m_saveMessage = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -35,8 +35,7 @@ class NoAuditLog : public Action {
|
||||
explicit NoAuditLog(const std::string &action)
|
||||
: Action(action) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
};
|
||||
|
||||
} // namespace actions
|
||||
|
@ -29,9 +29,8 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool NoLog::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
rm->m_saveMessage = false;
|
||||
bool NoLog::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {
|
||||
ruleMessage.m_saveMessage = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,7 @@ class NoLog : public Action {
|
||||
explicit NoLog(const std::string &action)
|
||||
: Action(action) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
};
|
||||
|
||||
} // namespace actions
|
||||
|
@ -26,11 +26,6 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool SetENV::init(std::string *error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SetENV::evaluate(RuleWithActions *rule, Transaction *t) {
|
||||
std::string colNameExpanded(m_string->evaluate(t));
|
||||
|
||||
|
@ -40,7 +40,6 @@ class SetENV : public Action {
|
||||
m_string(std::move(z)) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
|
||||
bool init(std::string *error) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<RunTimeString> m_string;
|
||||
|
@ -26,11 +26,6 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool SetRSC::init(std::string *error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SetRSC::evaluate(RuleWithActions *rule, Transaction *t) {
|
||||
std::string colNameExpanded(m_string->evaluate(t));
|
||||
ms_dbg_a(t, 8, "RESOURCE initiated with value: \'"
|
||||
|
@ -40,7 +40,6 @@ class SetRSC : public Action {
|
||||
m_string(std::move(z)) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
|
||||
bool init(std::string *error) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<RunTimeString> m_string;
|
||||
|
@ -26,11 +26,6 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool SetSID::init(std::string *error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SetSID::evaluate(RuleWithActions *rule, Transaction *t) {
|
||||
std::string colNameExpanded(m_string->evaluate(t));
|
||||
ms_dbg_a(t, 8, "Session ID initiated with value: \'"
|
||||
|
@ -40,7 +40,6 @@ class SetSID : public Action {
|
||||
m_string(std::move(z)) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
|
||||
bool init(std::string *error) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<RunTimeString> m_string;
|
||||
|
@ -26,11 +26,6 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool SetUID::init(std::string *error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SetUID::evaluate(RuleWithActions *rule, Transaction *t) {
|
||||
std::string colNameExpanded(m_string->evaluate(t));
|
||||
ms_dbg_a(t, 8, "User collection initiated with value: \'"
|
||||
|
@ -40,7 +40,6 @@ class SetUID : public Action {
|
||||
m_string(std::move(z)) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
|
||||
bool init(std::string *error) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<RunTimeString> m_string;
|
||||
|
@ -35,11 +35,6 @@ namespace modsecurity {
|
||||
namespace actions {
|
||||
|
||||
|
||||
bool SetVar::init(std::string *error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SetVar::evaluate(RuleWithActions *rule, Transaction *t) {
|
||||
std::string targetValue;
|
||||
std::string resolvedPre;
|
||||
|
@ -59,7 +59,6 @@ class SetVar : public Action {
|
||||
m_variable(std::move(variable)) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction) override;
|
||||
bool init(std::string *error) override;
|
||||
|
||||
private:
|
||||
SetVarOperation m_operation;
|
||||
|
@ -71,13 +71,12 @@ bool Severity::init(std::string *error) {
|
||||
}
|
||||
|
||||
|
||||
bool Severity::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
bool Severity::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {
|
||||
ms_dbg_a(transaction, 9, "This rule severity is: " + \
|
||||
std::to_string(this->m_severity) + " current transaction is: " + \
|
||||
std::to_string(transaction->m_highestSeverityAction));
|
||||
|
||||
rm->m_severity = m_severity;
|
||||
ruleMessage.m_severity = m_severity;
|
||||
|
||||
if (transaction->m_highestSeverityAction > this->m_severity) {
|
||||
transaction->m_highestSeverityAction = this->m_severity;
|
||||
|
@ -35,8 +35,7 @@ class Severity : public Action {
|
||||
: Action(action),
|
||||
m_severity(0) { }
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
bool init(std::string *error) override;
|
||||
|
||||
int m_severity;
|
||||
|
@ -57,12 +57,11 @@ std::string Tag::getName(Transaction *transaction) {
|
||||
}
|
||||
|
||||
|
||||
bool Tag::evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) {
|
||||
bool Tag::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {
|
||||
std::string tag = getName(transaction);
|
||||
ms_dbg_a(transaction, 9, "Rule tag: " + tag);
|
||||
|
||||
rm->m_tags.push_back(tag);
|
||||
ruleMessage.m_tags.push_back(tag);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -38,8 +38,7 @@ class Tag : public Action {
|
||||
|
||||
std::string getName(Transaction *transaction);
|
||||
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction,
|
||||
std::shared_ptr<RuleMessage> rm) override;
|
||||
bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<RunTimeString> m_string;
|
||||
|
@ -26,7 +26,7 @@ static inline int inplace(std::string &value) {
|
||||
|
||||
const auto len = value.length();
|
||||
auto d = reinterpret_cast<unsigned char *>(value.data());
|
||||
const auto data = d;
|
||||
const auto *data = d;
|
||||
|
||||
for (int i = 0; i <= len - 2; i += 2) {
|
||||
*d++ = utils::string::x2c(&data[i]);
|
||||
|
@ -62,18 +62,18 @@ static inline bool inplace(std::string &value) {
|
||||
}
|
||||
j++; /* j is the position of the first digit now. */
|
||||
|
||||
constexpr int MAX_HEX_DIGITS = 2; // supports only bytes (max value 0xff)
|
||||
auto k = j;
|
||||
while ((j - k < MAX_HEX_DIGITS) && (j < input_len) && (isxdigit(input[j]))) {
|
||||
while ((j < input_len) && (isxdigit(input[j]))) {
|
||||
j++;
|
||||
}
|
||||
if (j > k) { /* Do we have at least one digit? */
|
||||
/* Decode the entity. */
|
||||
char x[MAX_HEX_DIGITS + 1];
|
||||
memcpy(x, (const char *)&input[k], j - k);
|
||||
char *x = new char[(j - k) + 1];
|
||||
std::copy(input + k, input + j, x);
|
||||
x[j - k] = '\0';
|
||||
|
||||
*d++ = (unsigned char)strtol(x, nullptr, 16);
|
||||
delete[] x;
|
||||
|
||||
/* Skip over the semicolon if it's there. */
|
||||
if ((j < input_len) && (input[j] == ';')) {
|
||||
@ -87,18 +87,19 @@ static inline bool inplace(std::string &value) {
|
||||
}
|
||||
} else {
|
||||
/* Decimal entity. */
|
||||
constexpr int MAX_DEC_DIGITS = 3; // supports only bytes (max value 255)
|
||||
auto k = j;
|
||||
while ((j - k < MAX_DEC_DIGITS) && (j < input_len) && (isdigit(input[j]))) {
|
||||
|
||||
while ((j < input_len) && (isdigit(input[j]))) {
|
||||
j++;
|
||||
}
|
||||
if (j > k) { /* Do we have at least one digit? */
|
||||
/* Decode the entity. */
|
||||
char x[MAX_DEC_DIGITS + 1];
|
||||
memcpy(x, (const char *)&input[k], j - k);
|
||||
x[j - k] = '\0';
|
||||
char *x = new char[j - k + 1];
|
||||
std::copy(input + k, input + j, x);
|
||||
|
||||
x[j - k] = '\0';
|
||||
*d++ = (unsigned char)strtol(x, nullptr, 10);
|
||||
delete[] x;
|
||||
|
||||
/* Skip over the semicolon if it's there. */
|
||||
if ((j < input_len) && (input[j] == ';')) {
|
||||
@ -118,7 +119,7 @@ static inline bool inplace(std::string &value) {
|
||||
j++;
|
||||
}
|
||||
if (j > k) { /* Do we have at least one digit? */
|
||||
const auto x = reinterpret_cast<const char*>(&input[k]);
|
||||
const auto *x = reinterpret_cast<const char*>(&input[k]);
|
||||
|
||||
/* Decode the entity. */
|
||||
/* ENH What about others? */
|
||||
|
@ -29,9 +29,6 @@ bool NormalisePath::transform(std::string &value, const Transaction *trans) cons
|
||||
* IMP1 Assumes NUL-terminated
|
||||
*/
|
||||
bool NormalisePath::normalize_path_inplace(std::string &val, const bool win) {
|
||||
unsigned char *src;
|
||||
unsigned char *dst;
|
||||
unsigned char *end;
|
||||
int hitroot = 0;
|
||||
int done = 0;
|
||||
int relative;
|
||||
@ -49,13 +46,13 @@ bool NormalisePath::normalize_path_inplace(std::string &val, const bool win) {
|
||||
* ENH: Deal with UNC and drive letters?
|
||||
*/
|
||||
|
||||
src = dst = input;
|
||||
end = input + (input_len - 1);
|
||||
auto src = input;
|
||||
auto dst = input;
|
||||
const auto *end = input + (input_len - 1);
|
||||
|
||||
relative = ((*input == '/') || (win && (*input == '\\'))) ? 0 : 1;
|
||||
trailing = ((*end == '/') || (win && (*end == '\\'))) ? 1 : 0;
|
||||
|
||||
|
||||
while (!done && (src <= end) && (dst <= end)) {
|
||||
/* Convert backslash to forward slash on Windows only. */
|
||||
if (win) {
|
||||
@ -152,7 +149,7 @@ copy:
|
||||
|
||||
/* Skip to the last forward slash when multiple are used. */
|
||||
if (*src == '/') {
|
||||
unsigned char *oldsrc = src;
|
||||
const unsigned char *oldsrc = src;
|
||||
|
||||
while ((src < end)
|
||||
&& ((*(src + 1) == '/') || (win && (*(src + 1) == '\\'))) ) {
|
||||
|
@ -22,7 +22,7 @@ namespace modsecurity::actions::transformations {
|
||||
static inline bool inplace(std::string &value) {
|
||||
if (value.empty()) return false;
|
||||
|
||||
for(auto &c : value) {
|
||||
for(auto &c : value) { // cppcheck-suppress constVariableReference ; false positive
|
||||
((unsigned char&)c) &= 0x7f;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ static inline bool inplace(std::string &value) {
|
||||
|
||||
auto d = reinterpret_cast<unsigned char*>(value.data());
|
||||
const unsigned char *data = d;
|
||||
const auto end = data + value.size();
|
||||
const auto *end = data + value.size();
|
||||
|
||||
bool changed = false;
|
||||
|
||||
|
@ -46,7 +46,7 @@ static inline bool encode(std::string &value) {
|
||||
int unicode_len = 0;
|
||||
unsigned int d = 0;
|
||||
unsigned char c;
|
||||
auto utf = &input[i];
|
||||
const auto* utf = &input[i];
|
||||
|
||||
c = *utf;
|
||||
|
||||
|
@ -43,7 +43,7 @@ bool XmlNS::init(std::string *error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_href.at(0) == '\'' && m_href.size() > 3) {
|
||||
if (m_href[0] == '\'' && m_href.size() > 3) {
|
||||
m_href.erase(0, 1);
|
||||
m_href.pop_back();
|
||||
}
|
||||
|
@ -51,25 +51,13 @@ namespace modsecurity {
|
||||
namespace audit_log {
|
||||
|
||||
|
||||
AuditLog::AuditLog()
|
||||
: m_path1(""),
|
||||
m_path2(""),
|
||||
m_storage_dir(""),
|
||||
m_format(NotSetAuditLogFormat),
|
||||
m_parts(-1),
|
||||
m_filePermission(-1),
|
||||
m_directoryPermission(-1),
|
||||
m_status(NotSetLogStatus),
|
||||
m_type(NotSetAuditLogType),
|
||||
m_relevant(""),
|
||||
m_writer(NULL),
|
||||
m_ctlAuditEngineActive(false) { }
|
||||
AuditLog::AuditLog() = default;
|
||||
|
||||
|
||||
AuditLog::~AuditLog() {
|
||||
if (m_writer) {
|
||||
delete m_writer;
|
||||
m_writer = NULL;
|
||||
m_writer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,35 +96,42 @@ bool AuditLog::setStatus(AuditLogStatus status) {
|
||||
}
|
||||
|
||||
|
||||
bool AuditLog::setRelevantStatus(const std::basic_string<char>& status) {
|
||||
bool AuditLog::setRelevantStatus(std::string_view status) {
|
||||
this->m_relevant = std::string(status);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AuditLog::setStorageDir(const std::basic_string<char>& path) {
|
||||
bool AuditLog::setStorageDir(std::string_view path) {
|
||||
this->m_storage_dir = path;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AuditLog::setFilePath1(const std::basic_string<char>& path) {
|
||||
bool AuditLog::setFilePath1(std::string_view path) {
|
||||
this->m_path1 = path;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AuditLog::setFilePath2(const std::basic_string<char>& path) {
|
||||
bool AuditLog::setFilePath2(std::string_view path) {
|
||||
this->m_path2 = path;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AuditLog::setPrefix(std::string_view prefix) {
|
||||
this->m_prefix = prefix;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AuditLog::setFormat(AuditLogFormat fmt) {
|
||||
this->m_format = fmt;
|
||||
return true;
|
||||
}
|
||||
|
||||
int AuditLog::addParts(int parts, const std::string& new_parts) {
|
||||
int AuditLog::addParts(int parts, std::string_view new_parts) {
|
||||
PARTS_CONSTAINS('A', AAuditLogPart)
|
||||
PARTS_CONSTAINS('B', BAuditLogPart)
|
||||
PARTS_CONSTAINS('C', CAuditLogPart)
|
||||
@ -154,7 +149,7 @@ int AuditLog::addParts(int parts, const std::string& new_parts) {
|
||||
}
|
||||
|
||||
|
||||
int AuditLog::removeParts(int parts, const std::string& new_parts) {
|
||||
int AuditLog::removeParts(int parts, std::string_view new_parts) {
|
||||
PARTS_CONSTAINS_REM('A', AAuditLogPart)
|
||||
PARTS_CONSTAINS_REM('B', BAuditLogPart)
|
||||
PARTS_CONSTAINS_REM('C', CAuditLogPart)
|
||||
@ -172,7 +167,7 @@ int AuditLog::removeParts(int parts, const std::string& new_parts) {
|
||||
}
|
||||
|
||||
|
||||
bool AuditLog::setParts(const std::basic_string<char>& new_parts) {
|
||||
bool AuditLog::setParts(std::string_view new_parts) {
|
||||
int parts = 0;
|
||||
|
||||
PARTS_CONSTAINS('A', AAuditLogPart)
|
||||
@ -208,7 +203,6 @@ bool AuditLog::setType(AuditLogType audit_type) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool AuditLog::init(std::string *error) {
|
||||
audit_log::writer::Writer *tmp_writer;
|
||||
|
||||
@ -216,7 +210,7 @@ bool AuditLog::init(std::string *error) {
|
||||
&& !m_ctlAuditEngineActive) {
|
||||
if (m_writer) {
|
||||
delete m_writer;
|
||||
m_writer = NULL;
|
||||
m_writer = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -234,7 +228,7 @@ bool AuditLog::init(std::string *error) {
|
||||
tmp_writer = new audit_log::writer::Serial(this);
|
||||
}
|
||||
|
||||
if (tmp_writer == NULL) {
|
||||
if (tmp_writer == nullptr) {
|
||||
error->assign("Writer memory alloc failed!");
|
||||
return false;
|
||||
}
|
||||
@ -312,7 +306,7 @@ bool AuditLog::saveIfRelevant(Transaction *transaction, int parts) {
|
||||
}
|
||||
ms_dbg_a(transaction, 5, "Saving this request as part " \
|
||||
"of the audit logs.");
|
||||
if (m_writer == NULL) {
|
||||
if (m_writer == nullptr) {
|
||||
ms_dbg_a(transaction, 1, "Internal error, audit log writer is null");
|
||||
} else {
|
||||
std::string error;
|
||||
@ -337,6 +331,7 @@ bool AuditLog::merge(AuditLog *from, std::string *error) {
|
||||
AL_MERGE_STRING_CONF(from->m_path2, m_path2);
|
||||
AL_MERGE_STRING_CONF(from->m_storage_dir, m_storage_dir);
|
||||
AL_MERGE_STRING_CONF(from->m_relevant, m_relevant);
|
||||
AL_MERGE_STRING_CONF(from->m_prefix, m_prefix);
|
||||
|
||||
if (from->m_filePermission != -1) {
|
||||
m_filePermission = from->m_filePermission;
|
||||
|
@ -49,7 +49,7 @@ Parallel::~Parallel() {
|
||||
}
|
||||
|
||||
|
||||
inline std::string Parallel::logFilePath(time_t *t,
|
||||
inline std::string Parallel::logFilePath(const time_t *t,
|
||||
int part) {
|
||||
std::string name;
|
||||
|
||||
@ -119,11 +119,11 @@ bool Parallel::write(Transaction *transaction, int parts, std::string *error) {
|
||||
} else {
|
||||
std::string boundary;
|
||||
generateBoundary(&boundary);
|
||||
log = transaction->toOldAuditLogFormat(parts, "-" + boundary + "--");
|
||||
log = transaction->toOldAuditLogFormat(parts, "-" + boundary + "--", m_audit->m_prefix);
|
||||
}
|
||||
|
||||
const auto &logPath = m_audit->m_storage_dir;
|
||||
fileName = logPath + fileName + "-" + *transaction->m_id.get();
|
||||
fileName = logPath + fileName + "-" + transaction->m_id;
|
||||
|
||||
if (logPath.empty()) {
|
||||
error->assign("Log path is not valid.");
|
||||
|
@ -65,7 +65,7 @@ class Parallel : public Writer {
|
||||
YearMonthDayAndTimeFileName = 8,
|
||||
};
|
||||
|
||||
static inline std::string logFilePath(time_t *t, int part);
|
||||
static inline std::string logFilePath(const time_t *t, int part);
|
||||
};
|
||||
|
||||
} // namespace writer
|
||||
|
@ -42,7 +42,7 @@ bool Serial::write(Transaction *transaction, int parts, std::string *error) {
|
||||
} else {
|
||||
std::string boundary;
|
||||
generateBoundary(&boundary);
|
||||
msg = transaction->toOldAuditLogFormat(parts, "-" + boundary + "--");
|
||||
msg = transaction->toOldAuditLogFormat(parts, "-" + boundary + "--", m_audit->m_prefix);
|
||||
}
|
||||
|
||||
return utils::SharedFiles::getInstance().write(m_audit->m_path1, msg,
|
||||
|
@ -74,7 +74,7 @@ class InMemoryPerProcess :
|
||||
public Collection {
|
||||
public:
|
||||
explicit InMemoryPerProcess(const std::string &name);
|
||||
~InMemoryPerProcess();
|
||||
~InMemoryPerProcess() override;
|
||||
void store(const std::string &key, const std::string &value);
|
||||
|
||||
bool storeOrUpdateFirst(const std::string &key,
|
||||
|
@ -178,7 +178,7 @@ std::unique_ptr<std::string> LMDB::resolveFirst(const std::string& var) {
|
||||
|
||||
collectionData.setFromSerialized(reinterpret_cast<char *>(mdb_value_ret.mv_data), mdb_value_ret.mv_size);
|
||||
if ((!collectionData.isExpired()) && (collectionData.hasValue())) {
|
||||
ret = std::unique_ptr<std::string>(new std::string(collectionData.getValue()));
|
||||
ret = std::make_unique<std::string>(collectionData.getValue());
|
||||
}
|
||||
|
||||
end_get:
|
||||
@ -559,7 +559,7 @@ void LMDB::resolveMultiMatches(const std::string& var,
|
||||
continue;
|
||||
}
|
||||
|
||||
char *a = reinterpret_cast<char *>(key.mv_data);
|
||||
const char *a = reinterpret_cast<char *>(key.mv_data);
|
||||
if (strncmp(var.c_str(), a, keySize) == 0) {
|
||||
std::string key_to_insert(reinterpret_cast<char *>(key.mv_data), key.mv_size);
|
||||
l->insert(l->begin(), new VariableValue(&m_name, &key_to_insert, &collectionData.getValue()));
|
||||
|
@ -14,6 +14,7 @@
|
||||
#define pclose _pclose
|
||||
|
||||
inline tm* localtime_r(const time_t* tin, tm* tout) {
|
||||
// cppcheck-suppress[uninitvar, ctuuninitvar]
|
||||
if (!localtime_s(tout, tin)) return tout;
|
||||
|
||||
return nullptr;
|
||||
|
@ -114,14 +114,14 @@ int Lua::blob_keeper(lua_State *L, const void *p, size_t sz, void *ud) {
|
||||
|
||||
|
||||
const char *Lua::blob_reader(lua_State *L, void *ud, size_t *size) {
|
||||
LuaScriptBlob *lsb = static_cast<LuaScriptBlob *>(ud);
|
||||
const LuaScriptBlob *lsb = static_cast<LuaScriptBlob *>(ud);
|
||||
const char *data = lsb->read(size);
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int Lua::run(Transaction *t, const std::string &str) {
|
||||
int Lua::run(Transaction *t, const std::string &str) { // cppcheck-suppress constParameterPointer
|
||||
#ifdef WITH_LUA
|
||||
std::string luaRet;
|
||||
const char *a = NULL;
|
||||
|
@ -67,8 +67,8 @@ class Lua {
|
||||
public:
|
||||
Lua() { }
|
||||
|
||||
bool load(const std::string &script, std::string *err); // cppcheck-suppress functionStatic ; triggered when compiling without LUA
|
||||
int run(Transaction *t, const std::string &str = ""); // cppcheck-suppress functionStatic ; triggered when compiling without LUA
|
||||
bool load(const std::string &script, std::string *err);
|
||||
int run(Transaction *t, const std::string &str = "");
|
||||
static bool isCompatible(const std::string &script, Lua *l, std::string *error);
|
||||
|
||||
#ifdef WITH_LUA
|
||||
|
@ -190,26 +190,22 @@ const std::string& ModSecurity::getConnectorInformation() const {
|
||||
return m_connector;
|
||||
}
|
||||
|
||||
void ModSecurity::serverLog(void *data, std::shared_ptr<RuleMessage> rm) {
|
||||
void ModSecurity::serverLog(void *data, const RuleMessage &rm) {
|
||||
if (m_logCb == NULL) {
|
||||
std::cerr << "Server log callback is not set -- " << rm->errorLog();
|
||||
std::cerr << "Server log callback is not set -- " << rm.errorLog();
|
||||
std::cerr << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rm == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_logProperties & TextLogProperty) {
|
||||
auto d = rm->log();
|
||||
const void *a = static_cast<const void *>(d.c_str());
|
||||
auto d = rm.log();
|
||||
auto a = static_cast<const void *>(d.c_str());
|
||||
m_logCb(data, a);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_logProperties & RuleMessageLogProperty) {
|
||||
const void *a = static_cast<const void *>(rm.get());
|
||||
auto a = static_cast<const void *>(&rm);
|
||||
m_logCb(data, a);
|
||||
return;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user