Skip to content

hawkeyetw/wge

 
 

Repository files navigation

WGE

GitHub License GitHub Tag GitHub Repo Size Deploy Hugo site to GitHub Pages

English | 简体中文

What is WGE?

WGE is a high-performance web application firewall (WAF) library based on C++. It has been successfully applied in the commercial product Stone Rhino - Web Governance Engine (SR-WGE). It is designed to be compatible with the OWASP Core Rule Set (CRS) and can be used as a drop-in replacement for ModSecurity. The library is built using C++23 and is designed to be fast, efficient, and easy to use.

Performance Comparison

CPU: Intel(R) Core(TM) i5-10400 CPU @ 2.90GHz 2.90 GHz
RAM: 32GB
OS: Ubuntu 20.04.6 LTS (5.15.153.1-microsoft-standard-WSL2)
Worker Thread: 8
Input: White requests and Black requests

Test Case Enable Memory Pool(TCMalloc) ModSecurity WGE
CRS v4.3.0 No 4010 QPS 17560 QPS
CRS v4.3.0 Yes 4927 QPS 18864 QPS

The benchmark results show that WGE is significantly faster than ModSecurity, with a performance improvement of over 4 times. This is due to the use of modern C++ features and excellent architecture design and implementation. The library is designed to be easy to use and integrate into existing applications, making it a great choice for developers looking to add WAF functionality to their projects.

Features

  • Fully compatible with the OWASP Core Rule Set (CRS). Supports all variables, operators, and actions to ensure compatibility with existing rule sets. Effectively detects and defends against all attack types supported by CRS, including SQL injection (SQLI), cross-site scripting (XSS), local file inclusion (LFI), and remote command execution (RCE).
  • High performance. Uses Antlr4 to implement a high-performance front-end parser, a carefully designed efficient C++ object graph as the back-end interpreter, and integrates the TCMalloc memory pool to significantly improve throughput and reduce memory fragmentation.
  • Rich decoding support. Uses Ragel to implement a high-performance DFA codec engine, supporting 22 common decoding formats, including URL decoding, HTML entity decoding, JavaScript decoding, CSS decoding, etc., ensuring that attack payloads cannot bypass detection through encoding transformations.
  • Multi-threading support. Lock-free design supports efficient operation in multi-threaded environments, suitable for high-concurrency scenarios.
  • SecLang++. Derived from SecLang, SecLang++ introduces various practical language features such as rule fragments, configuration-driven rules, conditional actions, aliases, and reference variables, enhancing the flexibility and maintainability of rule writing.

Future Plans

  • Continuously evolve SecLang++, introducing more modern programming language features while maintaining the simplicity and ease of use of domain-specific languages, improving the expressiveness and maintainability of rule writing.
  • Add support for streaming processing, allowing large request/response bodies to be processed without loading the entire content into memory, reducing memory usage and preventing large request body attacks.
  • Add a syntax and semantic engine to reduce false positives and improve detection of complex attacks.
  • Introduce machine learning-assisted detection to enhance the identification of unknown attacks.
  • Add a multi-pattern matching detection engine to further improve rule execution efficiency.
  • Use bytecode + JIT technology to maximize rule execution efficiency.
  • Expand more connectors to demonstrate seamless integration with more web servers and frameworks.

Quick Start

Prerequisites

apt install ragel
  • JDK 21 or higher
apt install openjdk-21-jdk-headless
  • ANTLR4 4.13.2 or higher
cd /usr/local/lib
curl -O https://www.antlr.org/download/antlr-4.13.2-complete.jar
  • Configure the environment variables. Add the following to /etc/profile:
export CLASSPATH=".:/usr/local/lib/antlr-4.13.2-complete.jar:$CLASSPATH"
alias antlr4='java -Xmx500M -cp "/usr/local/lib/antlr-4.13.2-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
alias grun='java -Xmx500M -cp "/usr/local/lib/antlr-4.13.2-complete.jar:$CLASSPATH" org.antlr.v4.gui.TestRig'

Build

  • Update the submodule
git submodule update --init
  • Configure the cmake
cmake --preset=release-with-debug-info --fresh

If the compiler path is not in the default path, we can copy the CMakeUserPresets.json.example to CMakeUserPresets.json and modify the compiler path in the CMakeUserPresets.json file:

{
    "name": "my-release-with-debug-info",
    "inherits": "release-with-debug-info",
    "environment": {
    "CC": "/usr/local/bin/gcc",
    "CXX": "/usr/local/bin/g++",
    "LD_LIBRARY_PATH": "/usr/local/lib64"
    }
}

Then we can run the cmake command:

cmake --preset=my-release-with-debug-info --fresh

If we want to enable the debug log that help us to watch the process of WGE, we can set the WGE_LOG_ACTIVE_LEVEL to 1.

cmake --preset=release-with-debug-info --fresh -DWGE_LOG_ACTIVE_LEVEL=1

The WGE_LOG_ACTIVE_LEVEL is a compile-time option that controls the log level:
1: Trace
2: Debug
3: Info
4: Warn
5: Error
6: Critical
7: Off

  • Build with cmake
cmake --build build/release-with-debug-info

Run Unit Tests

./build/release-with-debug-info/test/test

Run Benchmark

./build/release-with-debug-info/benchmarks/wge/wge_benchmark

Integrate Into Existing Projects

  • Install WGE
cmake --install build/release-with-debug-info

After installation, the WGE library and header files will be available in the system include and library paths. We also can install the WGE into another path by specifying the --prefix option. For example, to install WGE into /specified/path, we can run:

cmake --install build/release-with-debug-info --prefix /specified/path
  • Include WGE in existing projects
#include <wge/engine.h>
  • Link WGE in existing projects
# If the WGE installed in the system path
target_link_libraries(your_target_name PRIVATE wge)
# If the WGE installed in the specified path
target_link_libraries(your_target_name PRIVATE /specified/path/lib/libwge.a)
  • Use WGE in existing projects
  1. Construct a WGE engine in the main thread
Wge::Engine engine(spdlog::level::off);
  1. Load the rules in the main thread
std::expected<bool, std::string> result = engine.loadFromFile(rule_file);
if (!result.has_value()) {
  // Handle the error
  std::cout << "Load rules error: " << result.error() << std::endl;
}
  1. Initialize the engine in the main thread
engine.init();
  1. Create a transaction when each request comes in the worker thread
// Each request has its own transaction
Wge::TransactionPtr t = engine.makeTransaction();
  1. Process the request in the worker thread
// Process each transaction is following the flowing steps
// 1. Process the connection
t->processConnection(/*params*/);
// 2. Process the URI
t->processUri(/*params*/);
// 3. Process the request headers
t->processRequestHeaders(/*params*/);
// 4. Process the request body
t->processRequestBody(/*params*/);
// 5. Process the response headers
t->processResponseHeaders(/*params*/);
// 6. Process the response body
t->processResponseBody(/*params*/);

Refer to the wge_benchmark for usage examples.

License

Copyright (c) 2024-2026 Stone Rhino and contributors. The WGE is distributed under MIT. Please see the enclosed LICENSE file for full details.

Documentation

  • Documentation Site: https://stone-rhino.github.io/wge We are working on the documentation for WGE. In the meantime, please refer to the source code and examples in the WGE-Connectors project for guidance on how to use the library.
  • WGE-Connectors: A collection of connectors for integrating WGE with various web servers and frameworks.

Contributing

We welcome contributions to WGE! If you have any ideas, suggestions, or bug reports, please open an issue or submit a pull request on GitHub. Before contributing, please read our CONTRIBUTING guidelines.

Contact

Stone Rhino

About

A high-performance web application firewall (WAF) library based on C++

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • C++ 82.3%
  • Ragel 10.8%
  • ANTLR 4.7%
  • CMake 1.2%
  • Other 1.0%