Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Default options
build --cxxopt='-std=c++17'
build --host_cxxopt='-std=c++17'
build --cxxopt='-O2'
build --experimental_scale_timeouts=10.0

# Windows options
build:windows --cxxopt='/std:c++17'
build:windows --host_cxxopt='/std:c++17'
1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8.3.1
17 changes: 17 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -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"
}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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-*
40 changes: 40 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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 = 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", "POCO_STATIC", "POCO_NO_AUTOMATIC_LIBS", "PCRE2_STATIC" ],
"//conditions:default": [],
}),
)
48 changes: 48 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module (
name = "modsecurity",
compatibility_level = 1,
)

bazel_dep(name = "rules_cc", version = "0.2.14")
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"],
)
""",
)
19 changes: 19 additions & 0 deletions examples/bazel/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cc_binary (
name = "main",
srcs = ["main.cc"],
deps = ["//:modsecurity", "@rules_cc//cc/runfiles"],
data = ["basic_rules.conf"],
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",
],
}),
)
10 changes: 10 additions & 0 deletions examples/bazel/basic_rules.conf
Original file line number Diff line number Diff line change
@@ -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"
106 changes: 106 additions & 0 deletions examples/bazel/main.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include <iostream>

#include <modsecurity/modsecurity.h>
#include <modsecurity/transaction.h>
#include <modsecurity/rules_set.h>
#include <modsecurity/rule_message.h>
#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<rules_cc::cc::runfiles::Runfiles> 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<modsecurity::ModSecurity>();
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<modsecurity::RulesSet>();
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<modsecurity::Transaction>(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;
}
}
35 changes: 35 additions & 0 deletions others/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
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",
],
exclude = [
"libinjection/src/fuzz/**",
],
),
hdrs = glob([
"libinjection/src/**/*.h",
]),
visibility = ["//visibility:public"],
defines = ["LIBINJECTION_VERSION=2"],
)
2 changes: 1 addition & 1 deletion src/actions/transformations/remove_whitespace.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<unsigned char>(c))
|| c == nonBreakingSpaces
Expand Down