Compare commits

...

175 Commits

Author SHA1 Message Date
Ervin Hegedus
a07ed61e74
Merge pull request #3432 from szedenik-adam/auditlog-header
Add custom leading text to audit log lines
2025-08-13 20:45:19 +03:00
szedenik-adam
4e2788eb47 Merge branch 'v3/master' into auditlog-header 2025-08-13 09:26:21 +02:00
Ervin Hegedus
f9f4011a4b
Merge pull request #3434 from airween/v3/cppcheckfix2
chore: fix cppcheck warning
2025-08-13 10:04:20 +03:00
Ervin Hegedus
62cb73f31d
Add const modifier to variable 2025-08-12 21:36:52 +02:00
Ervin Hegedus
8b3269f4d1
Try to avoid any kind of type casting 2025-08-12 21:05:31 +02:00
Ervin Hegedus
e879711d87
Add extra SonarCloud supression msg; Change type to auto 2025-08-11 23:05:32 +02:00
Ervin Hegedus
9fea1ca454
Change cast type (fix SonarCloud issues) 2025-08-11 22:41:07 +02:00
Ervin Hegedus
47bc24a808
Decrease code nest level 2025-08-11 22:28:22 +02:00
Ervin Hegedus
12809656a6
Remove redundant parenthesis 2025-08-11 22:02:37 +02:00
Ervin Hegedus
ea51a663f1
Move seclang-parser.hh supression to the right place 2025-08-11 17:19:46 +02:00
Ervin Hegedus
d19d3b4785
Supress uninitMemberVar warning in seclang-parser.hh 2025-08-11 16:43:58 +02:00
Ervin Hegedus
67f32a4e63
Fix cppcheck 2.18.0 warnings 2025-08-11 15:51:49 +02:00
szedenik-adam
6c6d94fc66 Renamed SecAuditLogHeader to SecAuditLogPrefix 2025-08-11 10:30:01 +02:00
szedenik-adam
0f402f33fd Adapted AuditLog based on code check hints 2025-08-07 11:01:44 +02:00
szedenik-adam
01c427f6be Replaced initializer list with in-class initializer in AuditLog 2025-08-07 10:23:50 +02:00
szedenik-adam
31fb9390c2 Replaced string parameters with string_view in AuditLog 2025-08-07 10:22:42 +02:00
szedenik-adam
2ee45de2fc Added audit log header 2025-08-04 17:09:49 +02:00
Ervin Hegedus
0ac551b070
Merge pull request #3430 from airween/v3/confvaluepathfix
fix: add Windows specific characters to config value syntax
2025-08-03 11:06:00 +03:00
Ervin Hegedus
013c8c2c7b
Remove escape from meta characters again 2025-08-01 13:28:19 +02:00
Ervin Hegedus
d8574c8c08
Fix date format pattern in auditlog's regression test 2025-08-01 11:38:39 +02:00
Ervin Hegedus
37948704df
Revert "Remove escape from meta characters"
This reverts commit 28bc3a98df54e251861d26dbb9f1374f622b97ea.
2025-08-01 09:33:22 +02:00
Ervin Hegedus
28bc3a98df
Remove escape from meta characters
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-08-01 09:11:20 +02:00
Ervin Hegedus
72e3abdd12
Add Windows specific characters to config value syntax in config parser 2025-07-30 14:37:27 +02:00
Ervin Hegedus
f2170d8576
Merge pull request #3426 from wooffie/fix-rx-476
fix: rx operators better null checks
2025-07-29 15:48:47 +03:00
Burkov Egor
c60709a58c fix: rx operators better null checks 2025-07-29 13:18:48 +03:00
Ervin Hegedus
1ff9f2a943
Merge pull request #3421 from airween/v3/secreqbodylimit
fix: integer type limits, 2nd try
2025-07-28 22:44:47 +03:00
Ervin Hegedus
690355b297
Merge pull request #3424 from wooffie/patch-1
fix: confusing indentation at acmp.cc
2025-07-28 19:07:27 +03:00
Burkov Egor
78b9cb7b57 Add more brackets 2025-07-28 15:11:02 +03:00
Burkov Egor
5d05ba359c
fix: confusing indentation at acmp.cc 2025-07-28 14:23:11 +03:00
Ervin Hegedus
9fb75d2c9a
Reformat code block with brackets
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-07-28 10:38:01 +02:00
Ervin Hegedus
abed778b4a
Remove unused ConfigDouble class 2025-07-27 17:28:26 +02:00
Ervin Hegedus
8d15991fb4
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-07-27 17:14:12 +02:00
Ervin Hegedus
b8a22bb67a
Update error message
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-07-27 17:09:11 +02:00
Ervin Hegedus
7e3c807c0d
Change syntax: add brackets to condition block 2025-07-27 17:07:12 +02:00
Ervin Hegedus
bb70ff06a4
Refactoring the cleaning of MATCHED_VAR* variables 2025-07-27 17:07:12 +02:00
Ervin Hegedus
08b70e006b
Merge pull request #3422 from airween/v3/matchedvarsfix2
Refactoring the cleaning of MATCHED_VAR* variables
2025-07-27 18:00:45 +03:00
Ervin Hegedus
79d55037c0
Refactoring the cleaning of MATCHED_VAR* variables 2025-07-25 14:33:24 +02:00
Ervin Hegedus
9a8ce8b5f5
Refactoring Config*Int types 2025-07-24 19:21:15 +02:00
Ervin Hegedus
cf24aeaead
Merge pull request #3405 from airween/v3/pmfromffix
fix: @pmFromFile with multiple files issue
2025-06-20 09:29:36 +02:00
Ervin Hegedus
6089b6b06b
Fix @pmFromFile with multiple files issue 2025-06-19 21:49:05 +02:00
Ervin Hegedus
31507404e6
Merge pull request #3392 from amezin/macaddr-resource-leak
Fix memory/socket leak in `UniqueId::ethernetMacAddress()`
2025-06-07 13:23:46 +02:00
Ervin Hegedus
f64ea2a708
Merge pull request #3390 from arvedarved/buildsystem-fixes
Buildsystem fixes
2025-06-07 09:06:04 +02:00
Ervin Hegedus
1362479d34
Merge pull request #3393 from JakubOnderka/json-log-hostname
Add hostname to JSON log
2025-05-28 22:55:57 +02:00
Jakub Onderka
8d3b2cacc4 Add hostname to JSON log 2025-05-28 16:24:09 +02:00
Aleksandr Mezin
a17193f7af Fix memory/socket leak in UniqueId::ethernetMacAddress()
Don't jump over `close()`/`free()`
2025-05-27 12:42:36 +03:00
Tilman Keskinöz
de624f9460
Attempt to fix bogus change.
Reported by: CI via Ervin Hegedus
2025-05-23 10:28:38 +02:00
Tilman Keskinöz
7660125da6
buildfix for srcdir != builddir
automake doesn't support wildcards.
See https://www.gnu.org/software/automake/manual/html_node/Wildcards.html
for details.

Use the GNU make $(wildcard ) extension.

Note: this breaks with non-GNU make
2025-05-22 18:59:56 +02:00
Tilman Keskinöz
0caf30679f
buildfix
If libxml2 is in a non-default directory, it needs to be added
to LDFLAGS
2025-05-22 18:59:55 +02:00
Tilman Keskinöz
0bcabf3208
buildfix for srcdir != builddir 2025-05-22 18:59:51 +02:00
Ervin Hegedus
aab47091b1
Merge pull request #3364 from JakubOnderka/json-logging
Simplify code for JSON audit log
2025-05-11 10:54:47 +02:00
Ervin Hegedus
990d99b1fb
Merge pull request #3365 from JakubOnderka/disable-expect
Disable Expect when sending audit logs to remote HTTP server
2025-05-11 10:50:10 +02:00
Ervin Hegedus
220caa5abc
Merge pull request #3363 from airween/v3/xmlargsfeat
feat: improved XMLArgs processing
2025-05-04 19:46:18 +02:00
Ervin Hegedus
a3876e3c99
Avoid unvanted content parse (whitespaces between tags) 2025-05-02 22:34:03 +02:00
Ervin Hegedus
d228ea6607
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-05-01 22:28:27 +02:00
Ervin Hegedus
89442ede16
Change directives in tests; add multibyte test case 2025-04-28 22:35:22 +02:00
Ervin Hegedus
e8dc60ee06
Change node value's parsing to concatenate instead of copy it every time 2025-04-28 22:34:26 +02:00
Ervin Hegedus
bf707de08f
Change directive format to strict camel case 2025-04-28 21:58:18 +02:00
Ervin Hegedus
0b62b7eb85
Align debug messages to fix regression tests 2025-04-27 21:09:49 +02:00
Ervin Hegedus
91a45e79bd
Update error message
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:28:30 +02:00
Ervin Hegedus
2135c8934e
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:28:07 +02:00
Ervin Hegedus
8947346cd4
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:27:47 +02:00
Ervin Hegedus
67429307cc
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:27:26 +02:00
Ervin Hegedus
0c7ea21a26
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:27:04 +02:00
Ervin Hegedus
72de7e8400
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:26:37 +02:00
Ervin Hegedus
0bf60208af
Add explanation
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:26:09 +02:00
Ervin Hegedus
2000f4c048
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:25:20 +02:00
Ervin Hegedus
159f6120aa
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:24:47 +02:00
Ervin Hegedus
bbe7eda693
Update explanation
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:23:02 +02:00
Ervin Hegedus
0fcd257fc4
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:22:14 +02:00
Ervin Hegedus
fedc70983c
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:21:45 +02:00
Ervin Hegedus
5b1c6fbf68
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:21:24 +02:00
Ervin Hegedus
eedfed873e
Update error message
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:21:03 +02:00
Ervin Hegedus
f0aa0700fe
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:20:49 +02:00
Ervin Hegedus
90be54e25e
Update error message
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:20:22 +02:00
Ervin Hegedus
3dc9fe990c
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:19:11 +02:00
Ervin Hegedus
e3678764e5
Update comment
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-04-27 20:18:47 +02:00
Ervin Hegedus
22fee1296d
Change owner in legal text 2025-04-26 20:54:36 +02:00
Jakub Onderka
b82d600049 Disable Expect when sending audit logs to remote HTTP server
This will speed-up sending logs to remote server
2025-04-23 16:19:30 +02:00
Jakub Onderka
797f7dc4b2 Change http_version field in JSON audit log to string
Sometimes m_httpVersion variable can be empty and then invalid JSON is generated
2025-04-23 10:59:10 +02:00
Jakub Onderka
6408bf9237 Test for JSON audit log 2025-04-22 21:09:42 +02:00
Jakub Onderka
37c0de363e Simplify code for JSON audit log 2025-04-22 19:41:08 +02:00
Ervin Hegedus
029684c294
Add nullptr check conditions 2025-04-20 21:35:54 +02:00
Ervin Hegedus
3e95614699
Add nullptr check conditions 2025-04-20 21:10:43 +02:00
Ervin Hegedus
b42602f400
Fix more cppcheck warning 2025-04-20 19:31:20 +02:00
Ervin Hegedus
8ae8374be5
Fix cppcheck errors 2025-04-20 19:01:45 +02:00
Ervin Hegedus
f62de58632
Added new cc and h files 2025-04-20 18:29:59 +02:00
Ervin Hegedus
9e41a53760
Finish XMLArgs processing in v3 2025-04-20 18:21:28 +02:00
Ervin Hegedus
01a0615887
Merge pull request #3354 from cjihrig/patch-1
doc: update testing section of README
2025-03-23 20:31:29 +01:00
Colin Ihrig
80019da75e
doc: update testing section of README
The regression_tests and unit_tests scripts appear to
be named with underscores instead of hyphens. This
commit updates the README to reflect this.
2025-03-23 12:59:02 -04:00
Ervin Hegedus
7a986c7bae
Merge pull request #3350 from airween/v3/cppcheckfix
fix: align code to fix cppcheck errors
2025-03-14 09:06:27 +01:00
Ervin Hegedus
8f00f4700f
Make destructor default; remove impmelentation 2025-03-12 23:07:43 +01:00
Ervin Hegedus
42280d213d
Make function argument const pointer 2025-03-12 22:26:29 +01:00
Ervin Hegedus
c3c2c6f280
Make variable const pointer 2025-03-12 22:19:00 +01:00
Ervin Hegedus
dbdd6318ff
Replace C pointers by shared pointer in fuzzy_hash op code 2025-03-12 22:09:51 +01:00
Ervin Hegedus
d3c1ad7177
Make utf variable const pointer 2025-03-12 22:07:46 +01:00
Ervin Hegedus
dc40880663
Fix cppcheck error in example multi.c 2025-03-12 20:45:47 +01:00
Ervin Hegedus
1a2b13967f
Merge pull request #3321 from gberkes/refactor/default-pcre2
Refactor/default pcre2
2025-03-12 18:16:35 +01:00
Ervin Hegedus
a555e5a445
Merge commit from fork
fix: fixed htmlEntityDecode methods
2025-02-25 14:50:05 +01:00
Ervin Hegedus
646881085c
Change release version to v3.0.14 2025-02-25 10:52:04 +01:00
Ervin Hegedus
29c3cc32e1
doc: update CHANGES 2025-02-24 18:35:13 +01:00
Ervin Hegedus
c82e831b66
fix: fixed htmlEntityDecode methods 2025-02-24 16:44:17 +01:00
Ervin Hegedus
f96806cd28
Merge pull request #3342 from airween/v3/gcc15fix
fix: Added missing header to avoid build error with gcc-15
2025-02-21 08:07:24 +01:00
Ervin Hegedus
71037dc4d7
fix: Added missing header to avoid build error with gcc-15 2025-02-20 13:36:35 +01:00
Gabor Berkes
d68aef320c refactor: improve maintainability for SonarCloud compliance
- Marked the conversion operator in `Pcre2MatchContextPtr` as `explicit`
  to improve type safety and prevent unintended implicit conversions.
- Ensured consistent use of `nullptr` instead of `NULL` for better readability and modern C++ compliance.

These changes enhance code clarity, maintainability, and adherence to modern C++ best practices.
2025-02-20 12:25:53 +00:00
Gabor Berkes
b97b61b711
Merge branch 'owasp-modsecurity:v3/master' into refactor/default-pcre2 2025-02-20 09:56:01 +01:00
Ervin Hegedus
40af573759
Merge pull request #3335 from RooHTaylor/v3/master
Fix for issue #3334: build not finding YAJL
2025-01-30 14:20:59 +01:00
Andrew Taylor
199056b916 Fix for issue #3334: build not finding YAJL
When searching for YAJL during ./configure, pkg-config is checked first,
and then a list of directories is searched if pkg-config bears no fruit.
The previous version of yajl.m4 was looping over YAJL_POSSIBLE_LIB_NAMES
instead of YAJL_POSSIBLE_PATHS and passing the lib name to the
CHECK_FOR_YAJL_AT() function instead of the path. The would lead to YAJL
never being found if pkg-config could not find it.
2025-01-30 01:19:50 -05:00
Ervin Hegedus
9e685bf86d
Merge pull request #3322 from airween/v3/validatebyterange
fix: add value checking to @validateByteRange
2025-01-06 19:16:49 +01:00
Ervin Hegedus
9158477561
Add check after intervall parsing, spell fix 2025-01-06 17:36:49 +01:00
Ervin Hegedus
4c5bc45dfd
Add value checking to @validateByteRange 2025-01-06 16:36:36 +01:00
Ervin Hegedus
f260a75c14
Merge pull request #3314 from ElevationsRPG/v3/master
Update README.md
2025-01-06 11:49:41 +01:00
Gabor Berkes
6a2eee629c
Merge branch 'owasp-modsecurity:v3/master' into refactor/default-pcre2 2025-01-06 09:02:00 +01:00
Elevations
d9acf3d0cd
Merge branch 'owasp-modsecurity:v3/master' into v3/master 2025-01-06 13:28:23 +13:00
Ervin Hegedus
eb7e2b8a5f
Merge pull request #3319 from airween/v3/osxcifix
fix: build library on OSX without GeoIP brew package
2025-01-05 17:05:30 +01:00
Ervin Hegedus
a332567b85
Set correct order of commands 2025-01-05 16:41:05 +01:00
Ervin Hegedus
72bb873460
Use latest released version by commit id.
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-01-05 16:09:03 +01:00
Ervin Hegedus
849131c8cf
Change depth value to 1 2025-01-04 23:46:09 +01:00
Ervin Hegedus
d76f3e741e
Update .github/workflows/ci.yml
Co-authored-by: Max Leske <250711+theseion@users.noreply.github.com>
2025-01-04 20:46:36 +01:00
Ervin Hegedus
900e7bcd06
Fix OSX build without GeoIP brew package 2025-01-04 13:48:39 +01:00
Gabor Berkes
10d1c2be74 Refactor: improve PCRE settings output in configure.ac
Enhanced the `configure.ac` script to provide clearer and more readable output for PCRE and PCRE2 settings during configuration. This change improves usability by ensuring that the configuration process displays relevant details in a structured and user-friendly format.

This update aligns with the broader PCRE to PCRE2 migration effort, making the build configuration process more transparent and consistent.
2024-12-20 08:12:06 +00:00
Gabor Berkes
e92507868e Fix macOS GitHub Actions build: add PCRE2_CFLAGS/LDADD/LDFLAGS
Introduced PCRE2_CFLAGS, PCRE2_LDADD, and PCRE2_LDFLAGS in all relevant Makefile.am files to align with the existing PCRE_* variable usage. This change addresses potential issues with linking and configuration for builds on macOS GitHub runners.

These modifications aim to resolve the build failure observed exclusively in the macOS environment while maintaining compatibility across other platforms. Testing will confirm if this adjustment corrects the issue.
2024-12-11 12:48:20 +00:00
Gabor Berkes
784cf0b64c Debug: increase verbosity in pcre2.m4 for macOS GitHub Actions
Added AC_MSG_NOTICE macros to pcre2.m4 to enhance debugging output. This change aims to identify the cause of build failures on macOS runners in GitHub Actions, which do not occur locally or on other platforms (Linux, Windows).

The added verbosity will help trace the build process and inspect variable values for inconsistencies in the macOS runner environment.
2024-12-11 08:57:43 +00:00
Elevations
c0681b6239
Update README.md
Remove conan center change
2024-12-11 19:29:32 +13:00
Elevations
7b4c3a2c0f
Update Dockerfile
Update Docker to latest conan version 2.10.2
2024-12-11 19:06:59 +13:00
Elevations
17700eca5b
Update README.md
Update Windows README to use latest conan version and conan center.
2024-12-11 17:45:37 +13:00
Gabor Berkes
a07d0c7d34 Fix missing libpcre2 dependency on macOS GitHub runner
Identified an issue where the macOS GitHub runner no longer includes the libpcre2 library by default. Updated the workflow configuration to explicitly add libpcre2 as a dependency, ensuring successful builds and compatibility with the updated build system.

This change prevents build failures on macOS environments and aligns the runner's setup with project requirements.
2024-12-10 21:40:09 +00:00
Gabor Berkes
106ed22b6d Fix typo in pcre.m4: corrected PCRE_CFLAGS assignment 2024-12-10 10:58:20 +00:00
Gabor Berkes
c6433df7b2 Refactor build system to use libpcre2 as the default
Updated the build system and related source files to use libpcre2 as the
default regex library instead of the deprecated libpcre. This change
ensures future compatibility and aligns with the library's maintenance status.

To build with the old libpcre, the `--with-pcre` configuration parameter
can be specified.
2024-12-10 10:16:14 +00:00
Gabor Berkes
4fb22466a0 Cleanup: Remove useless/nonfunctional AM_CONDITIONAL macros
- Deleted AM_CONDITIONAL macros from configure.ac that had no functional
  impact on the build system.
2024-12-10 07:32:13 +00:00
Ervin Hegedus
d9101a4fe1
Merge pull request #3306 from airween/v3/time_mon_fix
fix: align TIME_MON variable's behavior
2024-11-24 16:28:47 +00:00
Ervin Hegedus
daf550ef5f
Fix regex for test 2024-11-24 14:06:50 +01:00
Ervin Hegedus
db7e4cb67b
Align TIME_MON variable's behavior 2024-11-23 10:58:35 +01:00
Ervin Hegedus
fd4564131f
Merge pull request #3307 from gberkes/v3/cppcheck_v2_16_upgrade
Fix: Add false positive cppcheck-suppress for compatibility with upda…
2024-11-23 09:28:08 +00:00
Gabor Berkes
530919439b Fix: Add false positive cppcheck-suppress for compatibility with updated cppcheck version
- Added a cppcheck-suppress directive to handle a false positive detected
  by cppcheck 2.16.
- This change addresses an issue caused by the recent Homebrew update
  on macOS CI runner, which upgraded cppcheck from version 2.15 to 2.16.
2024-11-22 23:36:40 +00:00
Ervin Hegedus
41fd21b0fb
Merge pull request #3298 from airween/v3/sethostnamefix
Fix m_requestHostName variable behavior
2024-11-19 20:49:00 +00:00
Ervin Hegedus
d422b36966
Add condition before set hostname; move setRequestHostName() before processConnection() 2024-11-12 16:55:02 +01:00
Ervin Hegedus
4a720004dd
Merge pull request #3287 from hnakamur/fix_modsecurity-regression-test-secremoterules.txt_url_in_example
Fix modsecurity-regression-test-secremoterules.txt URL in example
2024-11-06 10:20:58 +00:00
Hiroaki Nakamura
42a401892b
Fix modsecurity-regression-test-secremoterules.txt URL in example 2024-11-06 14:33:28 +09:00
Ervin Hegedus
5bec188146
Merge pull request #3291 from hnakamur/add_test_regression_rules
Add regression rules for test
2024-11-05 11:03:04 +00:00
Hiroaki Nakamura
742f97ccc0
Add regression rules for test
Copied from:
- faa96c7838/modsecurity-regression-rules.txt
- b9321f190e/modsecurity-regression-ip-list.txt

diff --git a/test/test-cases/regression/operator-ipMatchFromFile.json b/test/test-cases/regression/operator-ipMatchFromFile.json
index 4a225954..1eb4d44a 100644
--- a/test/test-cases/regression/operator-ipMatchFromFile.json
+++ b/test/test-cases/regression/operator-ipMatchFromFile.json
@@ -129,7 +129,7 @@
     },
     "rules":[
       "SecRuleEngine On",
-      "SecRule REMOTE_ADDR \"@ipMatchFromFile b9321f190e/modsecurity-regression-ip-list.txt\" \"id:1
2024-11-02 20:17:24 +09:00
Ervin Hegedus
29a86b17df
Merge pull request #3283 from eduar-hte/cppcheck2142
Use latest version of cppcheck (2.15.0) to analyze codebase
2024-10-22 13:54:52 +02:00
Eduardo Arias
aca93f568e Remove no longer needed cppcheck inline suppressions. 2024-10-21 17:04:26 -03:00
Eduardo Arias
7ec50eb53f Make GeoLookup::debug function static (and non-member), as suggested by cppcheck. 2024-10-21 17:04:26 -03:00
Eduardo Arias
4e68edf0e5 Replace usage of sscanf with strtol to remove cppcheck inline suppression 2024-10-21 17:04:26 -03:00
Eduardo Arias
cdaf32f521 Remove cppcheck suppression by replacing use of local variable to alias this->m_variables
- The name of the local variable would clash with the namespace of the
  same name, which may have lead cppcheck to think the variable was not
  used.
2024-10-21 17:04:26 -03:00
Eduardo Arias
ce9a3167fa Use initialization list to initialize m_service
- This is correct because base class is initialized before members are
  initialized.
- Removes cppcheck suppression by addressing reported issue.
- Leverage C++11's 'default member initializer' to initialize m_provider
  & m_demandsPassword and address Sonarcloud issue.
2024-10-21 17:03:30 -03:00
Eduardo Arias
b0497d9cb9 Avoid this unnecessary copy by using a "const" reference.
- Reported by Sonarcloud
2024-10-19 15:27:39 -03:00
Eduardo Arias
d1e7e7b4f2 Refactor to remove duplicate code in ValidateSchema & ValidateDTD
- Reported by Sonarcloud
2024-10-19 15:27:39 -03:00
Eduardo Arias
2fb446ab2d Address cppcheck warnings generated after addressing Sonarcloud suggestions
- The following two warnings were generated after introducing the change
  to instantiate the DigestImpl template with the address of mbedtls_md5
  or mbedtls_sha1:
  - warning: src/utils/sha1.h,62,error,danglingTemporaryLifetime,Using
    pointer that is a temporary.
  - warning: src/utils/sha1.h,60,style,constVariablePointer,Variable
    'ret' can be declared as pointer to const
- See https://github.com/owasp-modsecurity/ModSecurity/pull/3231#issuecomment-2312511500
2024-10-19 11:48:05 -03:00
Eduardo Arias
bbef22b3b5 Added const reported by cppcheck 2.14 2024-10-19 11:48:05 -03:00
Eduardo Arias
d053ec6de6 Add cppcheck suppressions for false positives 2024-10-19 11:48:05 -03:00
Eduardo Arias
c2b86ddc49 Suppress warnings on seclang-parser.hh
warning: seclang-parser.hh,2116,warning,duplInheritedMember,The struct 'basic_symbol < by_kind >' defines member function with name 'clear' also defined in its parent struct 'by_kind'.
warning: seclang-parser.hh,2376,warning,duplInheritedMember,The struct 'basic_symbol < by_kind >' defines member function with name 'type_get' also defined in its parent struct 'by_kind'.
warning: seclang-parser.hh,2116,warning,duplInheritedMember,The struct 'basic_symbol < by_state >' defines member function with name 'clear' also defined in its parent struct 'by_state'.
warning: seclang-parser.hh,2120,style,constVariableReference,Variable 'yysym' can be declared as reference to const
2024-10-19 11:48:05 -03:00
Eduardo Arias
7d9c80dede Address cppcheck warnings: uselessOverride (The function '...' overrides a function in a base class but is identical to the overridden function) 2024-10-19 11:48:05 -03:00
Eduardo Arias
da38f20e19 Added missing override keyword as reported by cppcheck 2.14 2024-10-19 11:48:05 -03:00
Eduardo Arias
1eed8b9288 Ignore cppcheck warnings: normalCheckLevelMaxBranches (Limiting analysis of branches. Use --check-level=exhaustive to analyze all branches.) 2024-10-19 10:32:33 -03:00
Eduardo Arias
193a0002e4 Updated cppcheck config
- Do not scan third-party libraries (others dir)
- Use standard C++17 for checks (defaults to C++20)
2024-10-19 10:32:33 -03:00
Eduardo Arias
e0c58233ad Use latest version of cppcheck (2.14.2)
- Run cppcheck on MacOS to use a newer version of cppcheck
2024-10-19 10:32:33 -03:00
Ervin Hegedus
ec506daaef
Merge pull request #3280 from eduar-hte/range-checked-at
Replace usage of range-checked 'at' method when vector/string has already been size checked
2024-10-19 11:06:37 +02:00
Eduardo Arias
0613ceeb75 Replace usage of range-checked 'at' method when vector/string has already been size checked 2024-10-15 15:12:10 -03:00
Ervin Hegedus
99ce9779e6
Merge pull request #3253 from eduar-hte/rule-message
Simplified handling of RuleMessage by removing usage of std::shared_ptr
2024-10-15 18:13:31 +02:00
Eduardo Arias
75d31a4d1e Simplified lifetime management of tests
- Addresses Sonarcloud issues:
  - Rewrite the code so that you no longer need this "delete".
  - Make the type of this variable a reference-to-const.
2024-10-07 11:45:10 -03:00
Eduardo Arias
b7b2d9a40d Minor codebase improvements suggested by Sonarcloud
- src/modsecurity.cc
  - Replace the redundant type with "auto".
- src/transaction.cc
  - Avoid this unnecessary copy by using a "const" reference.
- test/common/custom_debug_log.cc
  - Use "=default" instead of the default implementation of this special
    member functions.
    - Removed the unnecessary destructor override instead.
  - Annotate this function with "override" or "final".
    - Removed the unnecessary destructor override instead.
  - Remove this "const" qualifier from the return type in all
    declarations.
- test/common/modsecurity_test_context.h
  - Replace the redundant type with "auto".
- test/regression/regression.cc
  - Use the "nullptr" literal.
  - Replace this declaration by a structured binding declaration.
  - Replace "reinterpret_cast" with a safer operation.
2024-10-07 11:45:10 -03:00
eduar-hte
4df297b596 Avoid passing RuleMessage by std::shared_ptr and use a reference instead.
- Avoids copying std::shared_ptr when lifetime of the RuleMessage
  is controlled by the caller.
  - The RuleMessage instance is created in RuleWithActions::evaluate and
    then used to call the overloaded version of this method that is
    specialized by subclasses.
  - Once the call to the overloaded method returns, the std::shared_ptr
    is destroyed as it's not stored by any of the callers, so it can
    be replaced with a stack variable and avoid paying the cost of
    copying the std::shared_ptr (and its control block that is
    guaranteed to be thread-safe and thus is not a straightforward
    pointer copy)
- Introduced RuleMessage::reset because this is required by
  RuleWithActions::performLogging when it's not the 'last log', the rule
  has multimatch and it's to be logged.
  - The current version is creating allocating another instance of
    RuleMessage on the heap to copy the Rule & Transaction related state
    while all the other members in the RuleMessage are set to their
    default values.
  - The new version leverages the existent, unused and incomplete
    function 'clean' (renamed as 'reset') to do this on the current
    instance.
    - Notice that the current code preserves the value of m_saveMessage,
      so 'reset' provides an argument for the caller to control whether
      this member should be reinitialized.
2024-10-07 11:45:00 -03:00
eduar-hte
e313ac7de7 Introduce ModSecurityTestContext to encapsulate setup of objects required to execute transactions
- Simplifies memory management on error conditions
- Context will be used in unit tests too, in order to provide
  Transaction related instances.
2024-10-07 11:45:00 -03:00
Ervin Hegedus
9a1155ca26
Merge pull request #3254 from eduar-hte/make_shared
Leverage std::make_unique & std::make_shared to create objects in the heap
2024-10-02 17:23:48 +02:00
Ervin Hegedus
373ddb8925
Merge pull request #3266 from airween/v3/modsecdefconf
chore: add 'log' action to rule 200005
2024-10-02 17:09:31 +02:00
Ervin Hegedus
63201ae39f
chore: add 'log' action to rule 200005 2024-10-02 16:33:56 +02:00
Ervin Hegedus
7737594edf
Merge pull request #3264 from xuruidong/logo2
docs: add a logo picture for github dark theme
2024-10-02 09:08:58 +02:00
xuruidong
9238b0ced0 docs: add a logo picture for github dark theme 2024-09-29 19:42:58 +08:00
Eduardo Arias
c6c06c4f33 leverage std::make_unique & std::make_shared
- Simpler code & more efficient because control block can be allocated
  with object.
2024-09-10 09:45:13 -03:00
Ervin Hegedus
9e02b3cf01
Merge pull request #3248 from eduar-hte/simplified-constructors
Simplified constructors, copy constructors & assignment operators
2024-09-09 16:14:09 +02:00
Eduardo Arias
6ecfee7ab7 Simplify and reduce code duplication in Transaction constructors
- Leverage delegating constructor to avoid code duplication between the
  two available Transaction constructors.
  - The constructor without 'id' argument delegates to the one that
    receives it by providing `nullptr` as a value, which is used to
    flag that an id needs to be generated.
- Simplified constructor by removing member initialization where the
  default constructor will be invoked.
2024-09-04 11:16:34 -03:00
Eduardo Arias
2c613fb77c Simplify initialization of fileName member of Rule instances 2024-09-04 10:51:21 -03:00
Eduardo Arias
2ad87f640f Reference RuleWithActions & Transaction object instead of copying values in RuleMessage
- Because the lifetime of the RuleMessage instances do not extend beyond
  the lifetime of the enclosing RuleWithActions & Transaction,
  RuleMessage can just reference it and simplify its definition.
- Additionally, make the references const to show that it doesn't modify it.
- Replace RuleMessage copy constructor with default implementations.
- Removed unused RuleMessage assignment operator (which cannot be implemented
  now that it has reference members).
- Removed constructor from RuleMessage pointer.
- Addressed Sonarcloud suggestions: Do not use the constructor's
  initializer list for data member "xxx". Use the in-class initializer
  instead.
2024-09-04 10:48:07 -03:00
Eduardo Arias
2ec640fd76 Delete unused copy constructor & assignment operator in Rule, RuleMarker & Action
- Declare other unsupported copy constructor & assignment operators as
  deleted too (RuleWithActions, RuleUnconditional & RuleScript)
2024-09-04 10:48:05 -03:00
221 changed files with 11302 additions and 9422 deletions

View File

@ -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
View File

@ -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
---------------------

View File

@ -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 .

View File

@ -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>
![Quality Assurance](https://github.com/owasp-modsecurity/ModSecurity/workflows/Quality%20Assurance/badge.svg)
[![Build Status](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=alert_status)](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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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]

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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++) {

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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");

View File

@ -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 = \

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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
};

View File

@ -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;

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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);

View File

@ -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);

View File

@ -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) \

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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 --------------------------------------------------

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -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) \

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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;
};

View 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

View 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_

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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; }
};

View File

@ -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;
}

View File

@ -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; }
};

View File

@ -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);

View File

@ -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; }
};

View File

@ -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;
}

View File

@ -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; }

View File

@ -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;

View File

@ -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'");

View File

@ -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:

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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));

View File

@ -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;

View File

@ -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: \'"

View File

@ -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;

View File

@ -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: \'"

View File

@ -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;

View File

@ -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: \'"

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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]);

View File

@ -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? */

View File

@ -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) == '\\'))) ) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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.");

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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()));

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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