From af8294382fcdcafc1557e07c236b9b65bb12c110 Mon Sep 17 00:00:00 2001 From: Varkeychan Jacob Date: Fri, 13 Feb 2026 10:48:12 +0000 Subject: [PATCH 1/5] get bazel build working --- .bazelrc | 5 ++ .bazelversion | 1 + .devcontainer/devcontainer.json | 17 +++++ .gitignore | 4 ++ BUILD.bazel | 27 ++++++++ MODULE.bazel | 7 +++ examples/bazel/BUILD.bazel | 16 +++++ examples/bazel/basic_rules.conf | 10 +++ examples/bazel/main.cc | 106 ++++++++++++++++++++++++++++++++ others/BUILD.bazel | 32 ++++++++++ 10 files changed, 225 insertions(+) create mode 100644 .bazelrc create mode 100644 .bazelversion create mode 100644 .devcontainer/devcontainer.json create mode 100644 BUILD.bazel create mode 100644 MODULE.bazel create mode 100644 examples/bazel/BUILD.bazel create mode 100644 examples/bazel/basic_rules.conf create mode 100644 examples/bazel/main.cc create mode 100644 others/BUILD.bazel diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000000..4444b77666 --- /dev/null +++ b/.bazelrc @@ -0,0 +1,5 @@ +# Default options +build --cxxopt='-std=c++17' +build --host_cxxopt='-std=c++17' +build --cxxopt='-O2' +build --experimental_scale_timeouts=10.0 \ No newline at end of file diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 0000000000..905c243928 --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +8.3.1 \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000..9336e81109 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,17 @@ +{ + "name": "libtraceable-dev", + "image": "ghcr.io/traceableai/native-build-images/ubuntu-20.04:0.1.98", + "mounts": [ + "source=${env:HOME}/.ssh,target=/home/builder/.ssh,type=bind,consistency=cached" + ], + "customizations": { + "vscode": { + "extensions": [ + "bazelbuild.vscode-bazel", + "ms-vscode.cpptools", + "ms-vscode.cpptools-extension-pack" + ] + } + }, + "remoteUser": "builder" +} diff --git a/.gitignore b/.gitignore index 4e314e466e..b6359c6514 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,7 @@ examples/multithread/multithread examples/reading_logs_via_rule_message/simple_request examples/reading_logs_with_offset/read examples/using_bodies_in_chunks/simple_request + +# bazel +MODULE.bazel.lock +bazel-* \ No newline at end of file diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 0000000000..5c752f98bd --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,27 @@ +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") + +cc_library( + name = "modsecurity", + srcs = glob( + [ + "src/**/*.h", + "src/**/*.hh", + "src/**/*.cc", + ], + ), + hdrs = glob([ + "headers/**/*.h", + ]), + includes = ["headers", "others"], + strip_include_prefix = "headers", + linkopts = select({ + "@platforms//os:linux": ["-lpthread"], + "@platforms//os:macos": ["-lpthread"], + "//conditions:default": [], + }), + visibility = ["//visibility:public"], + deps = [ + "//others:mbedtls", + "//others:libinjection", + ], +) \ No newline at end of file diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 0000000000..fa5b2cdde2 --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,7 @@ +module ( + name = "modsecurity", + compatibility_level = 1, +) + +bazel_dep(name = "rules_cc", version = "0.2.14") +bazel_dep(name = "platforms", version = "1.0.0") \ No newline at end of file diff --git a/examples/bazel/BUILD.bazel b/examples/bazel/BUILD.bazel new file mode 100644 index 0000000000..b4b0afbd56 --- /dev/null +++ b/examples/bazel/BUILD.bazel @@ -0,0 +1,16 @@ +cc_binary ( + name = "main", + srcs = ["main.cc"], + deps = ["//:modsecurity", "@rules_cc//cc/runfiles"], + data = ["basic_rules.conf"], + linkopts = [ + "-l:libpcre2-8.a", + "-ldl", + "-lstdc++fs", + "-lstdc++", + # "Ws2_32.lib", + # "Iphlpapi.lib", + # "pcre2-8-static.lib", + # "PocoFoundationmd.lib" + ] +) \ No newline at end of file diff --git a/examples/bazel/basic_rules.conf b/examples/bazel/basic_rules.conf new file mode 100644 index 0000000000..0d17471d82 --- /dev/null +++ b/examples/bazel/basic_rules.conf @@ -0,0 +1,10 @@ +SecRule REQUEST_HEADERS:User-Agent ".*" "id:100,phase:1,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{MATCHED_VAR}" + +SecAction "id:2,phase:2,initcol:ip=%{REMOTE_ADDR}_%{tx.ua_hash}" + +SecRule REQUEST_HEADERS:User-Agent "@rx .*" "id:3,phase:2,setvar:ip.auth_attempt=+1" +SecRule REQUEST_HEADERS:Jacob "@rx .*" "id:300,phase:2,setvar:ip.auth_attempt=+1,msg:'Matched value: %{MATCHED_VAR}'" +SecRule ARGS:foo "@rx herewego" "id:4,phase:2,setvar:ip.foo=bar,expirevar:ip.foo=2" +#SecRule ARGS:foo "@rx herewego" "id:4,phase:2,setvar:ip.foo=bar" +SecRule IP "@rx bar" "id:5,phase:2,pass" +SecRule IP:auth_attempt "@rx bar" "id:6,phase:2,pass" \ No newline at end of file diff --git a/examples/bazel/main.cc b/examples/bazel/main.cc new file mode 100644 index 0000000000..59e4ef0717 --- /dev/null +++ b/examples/bazel/main.cc @@ -0,0 +1,106 @@ +#include + +#include +#include +#include +#include +#include "rules_cc/cc/runfiles/runfiles.h" + + +void ModsecurityTest(const char* argv0); + +static const std::string GetTestConfPath(const char* argv0) { + std::string error; + std::unique_ptr runfiles( + rules_cc::cc::runfiles::Runfiles::Create(argv0, BAZEL_CURRENT_REPOSITORY, + &error)); + + if (!runfiles) { + std::cerr << "Failed to create Runfiles: " << error << "\n"; + return ""; + } + std::string repo_part = BAZEL_CURRENT_REPOSITORY; + if (repo_part.empty()) { + repo_part = "_main"; + } + + std::string logical_path = + repo_part + "/examples/bazel/basic_rules.conf"; + std::string physical_path = runfiles->Rlocation(logical_path); + + if (physical_path.empty()) { + return ""; + } + + return physical_path; +} + + +int main(int argc, char* argv[]) +{ + + std::cout << "Hello world!" << std::endl; + std::cout << "Test project for modsec windows is here!\n"; + try + { + ModsecurityTest(argv[0]); + } + catch (const std::exception &e) + { + std::cerr << "An error occurred: " << e.what() << std::endl; + } + return 0; +} + +void ModsecurityTest(const char* argv0) +{ + std::cout << "Starting ModSecurity test..." << std::endl; + std::cout << "About to create ModSecurity instance..." << std::endl; + std::cout.flush(); + auto modsec = std::make_unique(); + std::cout << "ModSecurity instance created." << std::endl; + std::cout << "ModSecurity whoAmI: " << modsec->whoAmI() << std::endl; + + std::cout << "About to create RulesSet..." << std::endl; + std::cout.flush(); + auto rules = std::make_unique(); + std::cout << "RulesSet created." << std::endl; + + std::string confPath = GetTestConfPath(argv0); + std::cout << "Config path: " << confPath << std::endl; + std::cout.flush(); + + if (rules->loadFromUri(confPath.c_str()) < 0) + { + std::cout<< "Failed to load rules from: " << confPath << std::endl; + std::cerr << "Problems loading the rules..." << std::endl; + std::cerr << rules->m_parserError.str() << std::endl; + return; + } + + std::cout<< "Rules loaded successfully from: " << confPath << std::endl; + auto modsecTransaction = std::make_unique(modsec.get(), rules.get(), nullptr); + modsecTransaction->processConnection("127.0.0.1", 12345, "127.0.0.1", 80); + modsecTransaction->processURI( + "https://www.modsecurity.org/test?foo=herewego", + "GET", "1.1"); + + modsecTransaction->addRequestHeader("User-Agent", + "Basic ModSecurity example"); + modsecTransaction->addRequestHeader("Jacob", + "matched-header"); + modsecTransaction->processRequestHeaders(); + modsecTransaction->processRequestBody(); + + modsecTransaction->addResponseHeader("HTTP/1.1", + "200 OK"); + modsecTransaction->processResponseHeaders(200, "HTTP 1.2"); + modsecTransaction->processResponseBody(); + + modsecTransaction->processLogging(); + + for (const auto &x : modsecTransaction->m_rulesMessages) + { + std::cout << std::to_string(x.m_rule.m_ruleId) << " " << x.m_message << std::endl; + } +} \ No newline at end of file diff --git a/others/BUILD.bazel b/others/BUILD.bazel new file mode 100644 index 0000000000..3b2a19b2c3 --- /dev/null +++ b/others/BUILD.bazel @@ -0,0 +1,32 @@ +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") + +cc_library( + name = "mbedtls", + srcs = glob( + [ + "mbedtls/library/**/*.h", + "mbedtls/library/**/*.c", + ], + ), + hdrs = glob([ + "mbedtls/include/**/*.h", + ]), + includes = ["mbedtls/include"], + strip_include_prefix = "mbedtls/include", + visibility = ["//visibility:public"], +) + +cc_library( + name = "libinjection", + srcs = glob( + [ + "libinjection/src/**/*.h", + "libinjection/src/**/*.c", + ], + ), + hdrs = glob([ + "libinjection/src/**/*.h", + ]), + visibility = ["//visibility:public"], + defines = ["LIBINJECTION_VERSION=2"], +) \ No newline at end of file From d89006551ee09f1f5e3a1c90847b30cf9a89fe8c Mon Sep 17 00:00:00 2001 From: Varkeychan Jacob Date: Fri, 13 Feb 2026 11:24:32 +0000 Subject: [PATCH 2/5] windows changes --- .bazelrc | 6 ++- BUILD.bazel | 7 +++ MODULE.bazel | 43 ++++++++++++++++++- examples/bazel/BUILD.bazel | 23 +++++----- others/BUILD.bazel | 3 ++ .../transformations/remove_whitespace.cc | 2 +- 6 files changed, 71 insertions(+), 13 deletions(-) diff --git a/.bazelrc b/.bazelrc index 4444b77666..1c571dc569 100644 --- a/.bazelrc +++ b/.bazelrc @@ -2,4 +2,8 @@ build --cxxopt='-std=c++17' build --host_cxxopt='-std=c++17' build --cxxopt='-O2' -build --experimental_scale_timeouts=10.0 \ No newline at end of file +build --experimental_scale_timeouts=10.0 + +# Windows options +build:windows --cxxopt='/std:c++17' +build:windows --host_cxxopt='/std:c++17' \ No newline at end of file diff --git a/BUILD.bazel b/BUILD.bazel index 5c752f98bd..daacc9a9b1 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -23,5 +23,12 @@ cc_library( deps = [ "//others:mbedtls", "//others:libinjection", + "@libxml2_conan//:libxml2_headers", + "@libpcre2_conan//:libpcre2_headers", + "@poco_conan//:poco_headers", ], + defines = select({ + "@platforms//os:windows": [ "WIN32", "LIBXML_STATIC" ], + "//conditions:default": [], + }), ) \ No newline at end of file diff --git a/MODULE.bazel b/MODULE.bazel index fa5b2cdde2..47ac815f70 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -4,4 +4,45 @@ module ( ) bazel_dep(name = "rules_cc", version = "0.2.14") -bazel_dep(name = "platforms", version = "1.0.0") \ No newline at end of file +bazel_dep(name = "platforms", version = "1.0.0") + +new_local_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:local.bzl", "new_local_repository") + +new_local_repository( + name = "libxml2_conan", + path = "C:/Conan/direct_deploy/libxml2", + build_file_content = """ +cc_library( + name = "libxml2_headers", + hdrs = glob(["include/libxml2/**/*.h"]), + strip_include_prefix = "include/libxml2", + visibility = ["//visibility:public"], +) +""", +) + +new_local_repository( + name = "libpcre2_conan", + path = "C:/Conan/direct_deploy/pcre2", + build_file_content = """ +cc_library( + name = "libpcre2_headers", + hdrs = glob(["include/**/*.h"]), + strip_include_prefix = "include", + visibility = ["//visibility:public"], +) +""", +) + +new_local_repository( + name = "poco_conan", + path = "C:/Conan/direct_deploy/poco", + build_file_content = """ +cc_library( + name = "poco_headers", + hdrs = glob(["include/**/*.h"]), + strip_include_prefix = "include", + visibility = ["//visibility:public"], +) +""", +) \ No newline at end of file diff --git a/examples/bazel/BUILD.bazel b/examples/bazel/BUILD.bazel index b4b0afbd56..38af6b0040 100644 --- a/examples/bazel/BUILD.bazel +++ b/examples/bazel/BUILD.bazel @@ -3,14 +3,17 @@ cc_binary ( srcs = ["main.cc"], deps = ["//:modsecurity", "@rules_cc//cc/runfiles"], data = ["basic_rules.conf"], - linkopts = [ - "-l:libpcre2-8.a", - "-ldl", - "-lstdc++fs", - "-lstdc++", - # "Ws2_32.lib", - # "Iphlpapi.lib", - # "pcre2-8-static.lib", - # "PocoFoundationmd.lib" - ] + linkopts = select({ + "@platforms//os:windows": [ + "/LIBPATH:C:/Conan/Libs", + "Ws2_32.lib", + "Iphlpapi.lib", + "pcre2-8-static.lib", + "PocoFoundationmd.lib", + "libxml2_a.lib", + ], + "//conditions:default": [ + "-l:libpcre2-8.a", + ], + }), ) \ No newline at end of file diff --git a/others/BUILD.bazel b/others/BUILD.bazel index 3b2a19b2c3..47035dc0f6 100644 --- a/others/BUILD.bazel +++ b/others/BUILD.bazel @@ -23,6 +23,9 @@ cc_library( "libinjection/src/**/*.h", "libinjection/src/**/*.c", ], + exclude = [ + "libinjection/src/fuzz/**", + ], ), hdrs = glob([ "libinjection/src/**/*.h", diff --git a/src/actions/transformations/remove_whitespace.cc b/src/actions/transformations/remove_whitespace.cc index f7047f4760..78796527b1 100644 --- a/src/actions/transformations/remove_whitespace.cc +++ b/src/actions/transformations/remove_whitespace.cc @@ -24,7 +24,7 @@ bool RemoveWhitespace::transform(std::string &value, const Transaction *trans) c const char nonBreakingSpaces = 0xa0; const char nonBreakingSpaces2 = 0xc2; - auto pred = [](const auto c) { + auto pred = [nonBreakingSpaces, nonBreakingSpaces2](const auto c) { // remove whitespaces and non breaking spaces (NBSP) return std::isspace(static_cast(c)) || c == nonBreakingSpaces From 1e205f6b24d501868e4db74de499fbd958e6defd Mon Sep 17 00:00:00 2001 From: Varkeychan Jacob Date: Fri, 13 Feb 2026 11:26:07 +0000 Subject: [PATCH 3/5] update bazel build --- BUILD.bazel | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index daacc9a9b1..5e0e23648c 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -20,13 +20,19 @@ cc_library( "//conditions:default": [], }), visibility = ["//visibility:public"], - deps = [ - "//others:mbedtls", - "//others:libinjection", - "@libxml2_conan//:libxml2_headers", - "@libpcre2_conan//:libpcre2_headers", - "@poco_conan//:poco_headers", - ], + deps = select({ + "@platforms//os:windows": [ + "//others:mbedtls", + "//others:libinjection", + "@libxml2_conan//:libxml2_headers", + "@libpcre2_conan//:libpcre2_headers", + "@poco_conan//:poco_headers", + ], + "//conditions:default": [ + "//others:mbedtls", + "//others:libinjection", + ], + }), defines = select({ "@platforms//os:windows": [ "WIN32", "LIBXML_STATIC" ], "//conditions:default": [], From d7f385982b7af6967f9afb4f7389a99c9e8c3a7b Mon Sep 17 00:00:00 2001 From: Varkeychan Jacob Date: Fri, 13 Feb 2026 16:58:14 +0530 Subject: [PATCH 4/5] add poco defines --- BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD.bazel b/BUILD.bazel index 5e0e23648c..b0c0414482 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -34,7 +34,7 @@ cc_library( ], }), defines = select({ - "@platforms//os:windows": [ "WIN32", "LIBXML_STATIC" ], + "@platforms//os:windows": [ "WIN32", "LIBXML_STATIC", "POCO_STATIC", "POCO_NO_AUTOMATIC_LIBS" ], "//conditions:default": [], }), ) \ No newline at end of file From 4300cab929ff8bb8a7494be53ca97a50479ee51b Mon Sep 17 00:00:00 2001 From: Varkeychan Jacob Date: Fri, 13 Feb 2026 17:03:07 +0530 Subject: [PATCH 5/5] add pcre2 defines --- BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD.bazel b/BUILD.bazel index b0c0414482..3ce935ba9e 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -34,7 +34,7 @@ cc_library( ], }), defines = select({ - "@platforms//os:windows": [ "WIN32", "LIBXML_STATIC", "POCO_STATIC", "POCO_NO_AUTOMATIC_LIBS" ], + "@platforms//os:windows": [ "WIN32", "LIBXML_STATIC", "POCO_STATIC", "POCO_NO_AUTOMATIC_LIBS", "PCRE2_STATIC" ], "//conditions:default": [], }), ) \ No newline at end of file