Skip to content

Commit

Permalink
Merge branch 'owasp-modsecurity:v3/master' into v3/sethostname
Browse files Browse the repository at this point in the history
  • Loading branch information
airween authored Aug 1, 2024
2 parents 937fc5a + a14cdc4 commit c7efeb6
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 13 deletions.
81 changes: 80 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ As a dynamic library, don’t forget that libmodsecurity must be installed to a

### Unix (Linux, MacOS, FreeBSD, …)

On unix the project uses autotools to help the compilation process.
On unix the project uses autotools to help the compilation process. Please note that if you are working with `git`, don't forget to initialize and update the submodules. Here's a quick how-to:
```shell
$ git clone --recursive https://github.com/owasp-modsecurity/ModSecurity ModSecurity
$ cd ModSecurity
```

You can then start the build process:

```shell
$ ./build.sh
Expand Down Expand Up @@ -235,6 +241,79 @@ $ make
$ sudo make install
```

### Benchmarking

The source tree includes a Benchmark tool that can help measure library performance. The tool is located in the `test/benchmark/` directory. The build process also creates the binary here, so you will have the tool after the compilation is finished.

To run, just type:

```shell
cd test/benchmark
$ ./benchmark
Doing 1000000 transactions...

```

You can also pass a lower value:

```shell
$ ./benchmark 1000
Doing 1000 transactions...
```

To measure the time:
```shell
$ time ./benchmark 1000
Doing 1000 transactions...

real 0m0.351s
user 0m0.337s
sys 0m0.022s
```

This is very fast because the benchmark uses the minimal `modsecurity.conf.default` configuration, which doesn't include too many rules:

```shell
$ cat basic_rules.conf

Include "../../modsecurity.conf-recommended"

```

To measure with real rules, run one of the download scripts in the same directory:

```shell
$ ./download-owasp-v3-rules.sh
Cloning into 'owasp-v3'...
remote: Enumerating objects: 33007, done.
remote: Counting objects: 100% (2581/2581), done.
remote: Compressing objects: 100% (907/907), done.
remote: Total 33007 (delta 2151), reused 2004 (delta 1638), pack-reused 30426
Receiving objects: 100% (33007/33007), 9.02 MiB | 16.21 MiB/s, done.
Resolving deltas: 100% (25927/25927), done.
Switched to a new branch 'tag3.0.2'
/path/to/ModSecurity/test/benchmark
Done.

$ cat basic_rules.conf

Include "../../modsecurity.conf-recommended"

Include "owasp-v3/crs-setup.conf.example"
Include "owasp-v3/rules/*.conf"
```

Now the command will give much higher value.

#### How the benchmark works

The tool is a straightforward wrapper application that utilizes the library. It creates a ModSecurity instance and a RuleSet instance, then runs a loop based on the specified number. Within this loop, it creates a Transaction object to emulate real HTTP transactions.

Each transaction is an HTTP/1.1 GET request with some GET parameters. Common headers are added, followed by the response headers and an XML body. Between phases, the tool checks whether an intervention has occurred. All transactions are created with the same data.

Note that the tool does not call the last phase (logging).

Please remember to reset `basic_rules.conf` if you want to try with a different ruleset.

## Reporting Issues

Expand Down
9 changes: 4 additions & 5 deletions src/anchored_set_variable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,11 @@ void AnchoredSetVariable::resolve(const std::string &key,

std::unique_ptr<std::string> AnchoredSetVariable::resolveFirst(
const std::string &key) {
auto range = equal_range(key);
for (auto it = range.first; it != range.second; ++it) {
std::unique_ptr<std::string> b(new std::string());
b->assign(it->second->getValue());
return b;

if (auto search = this->find(key); search != this->end()) {
return std::make_unique<std::string>(search->second->getValue());
}

return nullptr;
}

Expand Down
14 changes: 7 additions & 7 deletions src/collection/backend/in_memory-per_process.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ bool InMemoryPerProcess::storeOrUpdateFirst(const std::string &key,
bool InMemoryPerProcess::updateFirst(const std::string &key,
const std::string &value) {
pthread_mutex_lock(&m_lock);
auto range = this->equal_range(key);

for (auto it = range.first; it != range.second; ++it) {
it->second.setValue(value);
if (auto search = this->find(key); search != this->end()) {
search->second.setValue(value);
pthread_mutex_unlock(&m_lock);
return true;
}

pthread_mutex_unlock(&m_lock);
return false;
}
Expand All @@ -97,11 +97,11 @@ void InMemoryPerProcess::delIfExpired(const std::string& key) {

void InMemoryPerProcess::setExpiry(const std::string& key, int32_t expiry_seconds) {
pthread_mutex_lock(&m_lock);
auto range = this->equal_range(key);
for (auto it = range.first; it != range.second; ++it) {
it->second.setExpiry(expiry_seconds);

if (auto search = this->find(key); search != this->end()) {
search->second.setExpiry(expiry_seconds);
pthread_mutex_unlock(&m_lock);
return;
return;
}

// We allow an expiry value to be set for a key that has not (yet) had a value set.
Expand Down

0 comments on commit c7efeb6

Please sign in to comment.