Skip to content

Commit ccccfe0

Browse files
committed
Initial release - Web Application Firewall agent
Features: - SQL injection detection (UNION, blind, time-based) - Cross-Site Scripting (XSS) detection - Path traversal detection - Command injection detection - Protocol attack detection - Configurable paranoia levels (1-4) - Detect-only mode for monitoring Pure Rust implementation - no external dependencies. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
0 parents  commit ccccfe0

File tree

7 files changed

+1054
-0
lines changed

7 files changed

+1054
-0
lines changed

.github/workflows/ci.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
RUST_BACKTRACE: 1
12+
13+
jobs:
14+
build:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Install Rust
20+
uses: dtolnay/rust-toolchain@stable
21+
22+
- name: Cache cargo
23+
uses: actions/cache@v4
24+
with:
25+
path: |
26+
~/.cargo/registry
27+
~/.cargo/git
28+
target
29+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
30+
31+
- name: Build
32+
run: cargo build --release
33+
34+
- name: Run tests
35+
run: cargo test
36+
37+
- name: Check formatting
38+
run: cargo fmt -- --check
39+
40+
- name: Run clippy
41+
run: cargo clippy -- -D warnings

.github/workflows/release.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
env:
9+
CARGO_TERM_COLOR: always
10+
11+
jobs:
12+
publish:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Install Rust
18+
uses: dtolnay/rust-toolchain@stable
19+
20+
- name: Publish to crates.io
21+
run: cargo publish
22+
env:
23+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
24+
25+
release:
26+
needs: publish
27+
runs-on: ubuntu-latest
28+
steps:
29+
- uses: actions/checkout@v4
30+
31+
- name: Install Rust
32+
uses: dtolnay/rust-toolchain@stable
33+
34+
- name: Build release binary
35+
run: |
36+
cargo build --release
37+
strip target/release/sentinel-waf-agent
38+
39+
- name: Create release
40+
uses: softprops/action-gh-release@v1
41+
with:
42+
files: |
43+
target/release/sentinel-waf-agent
44+
generate_release_notes: true

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/target
2+
Cargo.lock
3+
*.sock
4+
.env

Cargo.toml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
[package]
2+
name = "sentinel-agent-waf"
3+
version = "0.1.0"
4+
edition = "2021"
5+
rust-version = "1.75"
6+
authors = ["Sentinel Contributors"]
7+
license = "MIT OR Apache-2.0"
8+
repository = "https://github.com/raskell-io/sentinel-agent-waf"
9+
homepage = "https://sentinel.raskell.io"
10+
documentation = "https://sentinel.raskell.io/docs/agents/waf"
11+
description = "Web Application Firewall agent for Sentinel reverse proxy - SQL injection, XSS, and attack detection"
12+
keywords = ["proxy", "reverse-proxy", "agent", "waf", "security"]
13+
categories = ["network-programming"]
14+
readme = "README.md"
15+
16+
[[bin]]
17+
name = "sentinel-waf-agent"
18+
path = "src/main.rs"
19+
20+
[dependencies]
21+
# Sentinel protocol
22+
sentinel-agent-protocol = "0.1"
23+
sentinel-common = "0.1"
24+
25+
# Async runtime
26+
tokio = { version = "1.40", features = ["full"] }
27+
async-trait = "0.1"
28+
29+
# Pattern matching
30+
regex = "1.10"
31+
32+
# Serialization
33+
serde = { version = "1.0", features = ["derive"] }
34+
serde_json = "1.0"
35+
36+
# Logging
37+
tracing = "0.1"
38+
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
39+
40+
# Error handling
41+
anyhow = "1.0"
42+
thiserror = "1.0"
43+
44+
# Command line
45+
clap = { version = "4.5", features = ["derive", "env"] }
46+
47+
[dev-dependencies]
48+
tempfile = "3.12"

README.md

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# sentinel-agent-waf
2+
3+
Web Application Firewall agent for [Sentinel](https://github.com/raskell-io/sentinel) reverse proxy. Detects and blocks common web attacks.
4+
5+
## Features
6+
7+
- **SQL Injection detection** - UNION-based, blind, time-based
8+
- **Cross-Site Scripting (XSS)** - Script tags, event handlers, JavaScript URIs
9+
- **Path Traversal** - Directory traversal, encoded attacks
10+
- **Command Injection** - Shell commands, pipe injection
11+
- **Protocol Attacks** - Request smuggling, scanner detection
12+
- **Paranoia levels** (1-4) for tuning sensitivity
13+
- **Detect-only mode** for monitoring without blocking
14+
15+
## Installation
16+
17+
### From crates.io
18+
19+
```bash
20+
cargo install sentinel-agent-waf
21+
```
22+
23+
### From source
24+
25+
```bash
26+
git clone https://github.com/raskell-io/sentinel-agent-waf
27+
cd sentinel-agent-waf
28+
cargo build --release
29+
```
30+
31+
## Usage
32+
33+
```bash
34+
sentinel-waf-agent --socket /var/run/sentinel/waf.sock --paranoia-level 1
35+
```
36+
37+
### Command Line Options
38+
39+
| Option | Environment Variable | Description | Default |
40+
|--------|---------------------|-------------|---------|
41+
| `--socket` | `AGENT_SOCKET` | Unix socket path | `/tmp/sentinel-waf.sock` |
42+
| `--paranoia-level` | `WAF_PARANOIA_LEVEL` | Sensitivity (1-4) | `1` |
43+
| `--sqli` | `WAF_SQLI` | Enable SQL injection detection | `true` |
44+
| `--xss` | `WAF_XSS` | Enable XSS detection | `true` |
45+
| `--path-traversal` | `WAF_PATH_TRAVERSAL` | Enable path traversal detection | `true` |
46+
| `--command-injection` | `WAF_COMMAND_INJECTION` | Enable command injection detection | `true` |
47+
| `--protocol` | `WAF_PROTOCOL` | Enable protocol attack detection | `true` |
48+
| `--block-mode` | `WAF_BLOCK_MODE` | Block (true) or detect-only (false) | `true` |
49+
| `--exclude-paths` | `WAF_EXCLUDE_PATHS` | Paths to exclude (comma-separated) | - |
50+
| `--verbose` | `WAF_VERBOSE` | Enable debug logging | `false` |
51+
52+
## Paranoia Levels
53+
54+
| Level | Description |
55+
|-------|-------------|
56+
| 1 | High-confidence detections only (recommended for production) |
57+
| 2 | Adds medium-confidence rules, more false positives possible |
58+
| 3 | Adds low-confidence rules, requires tuning |
59+
| 4 | Maximum sensitivity, expect false positives |
60+
61+
## Detection Rules
62+
63+
### SQL Injection (942xxx)
64+
- UNION-based injection
65+
- Tautology attacks (`OR 1=1`)
66+
- Comment injection (`--`, `#`, `/**/`)
67+
- Time-based blind injection (`SLEEP()`, `BENCHMARK()`)
68+
69+
### Cross-Site Scripting (941xxx)
70+
- Script tag injection (`<script>`)
71+
- Event handler injection (`onclick=`, `onerror=`)
72+
- JavaScript URI (`javascript:`)
73+
- Data URI (`data:text/html`)
74+
75+
### Path Traversal (930xxx)
76+
- Directory traversal (`../`, `..\\`)
77+
- URL-encoded traversal (`%2e%2e%2f`)
78+
- OS file access (`/etc/passwd`, `c:\\windows`)
79+
80+
### Command Injection (932xxx)
81+
- Shell command injection (`; ls`, `| cat`)
82+
- Unix command execution (`$(...)`, backticks)
83+
- Windows command execution (`cmd.exe`, `powershell`)
84+
85+
### Protocol Attacks (920xxx)
86+
- Control characters in request
87+
- Request smuggling patterns
88+
- Scanner detection (Nikto, SQLMap, etc.)
89+
90+
## Configuration
91+
92+
### Sentinel Proxy Configuration
93+
94+
```kdl
95+
agents {
96+
agent "waf" {
97+
type "custom"
98+
transport "unix_socket" {
99+
path "/var/run/sentinel/waf.sock"
100+
}
101+
events ["request_headers"]
102+
timeout-ms 50
103+
failure-mode "open"
104+
}
105+
}
106+
107+
routes {
108+
route "all" {
109+
matches { path-prefix "/" }
110+
upstream "backend"
111+
agents ["waf"]
112+
}
113+
}
114+
```
115+
116+
### Docker/Kubernetes
117+
118+
```yaml
119+
# Environment variables
120+
WAF_PARANOIA_LEVEL: "1"
121+
WAF_BLOCK_MODE: "true"
122+
WAF_EXCLUDE_PATHS: "/health,/metrics"
123+
```
124+
125+
## Response Headers
126+
127+
On blocked requests:
128+
- `X-WAF-Blocked: true`
129+
- `X-WAF-Rule: <rule_id>`
130+
131+
In detect-only mode, the request continues but includes:
132+
- `X-WAF-Detected: <rule_ids>`
133+
134+
## Excluding Paths
135+
136+
Exclude paths from WAF inspection:
137+
138+
```bash
139+
sentinel-waf-agent --exclude-paths "/health,/metrics,/static"
140+
```
141+
142+
## False Positive Handling
143+
144+
1. **Lower paranoia level** - Start with level 1 and increase gradually
145+
2. **Exclude paths** - Exclude known-safe endpoints
146+
3. **Detect-only mode** - Monitor before enabling blocking
147+
4. **Custom rules** - Future feature for rule customization
148+
149+
## Comparison with ModSecurity
150+
151+
This agent provides a subset of ModSecurity's OWASP CRS functionality:
152+
153+
| Feature | This Agent | ModSecurity |
154+
|---------|------------|-------------|
155+
| SQL Injection | ✓ | ✓ |
156+
| XSS | ✓ | ✓ |
157+
| Path Traversal | ✓ | ✓ |
158+
| Command Injection | ✓ | ✓ |
159+
| Full CRS Ruleset | Partial | ✓ |
160+
| Body Inspection | - | ✓ |
161+
| Custom Rules | - | ✓ |
162+
| Dependencies | Pure Rust | libmodsecurity |
163+
| Installation | `cargo install` | Complex |
164+
165+
For full OWASP CRS compatibility, consider using ModSecurity with Sentinel's external processing.
166+
167+
## Development
168+
169+
```bash
170+
# Run with debug logging
171+
RUST_LOG=debug cargo run -- --socket /tmp/test.sock --paranoia-level 2
172+
173+
# Run tests
174+
cargo test
175+
```
176+
177+
## License
178+
179+
MIT OR Apache-2.0

sentinel-agent.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Sentinel Agent Registry Manifest
2+
# WAF Agent - Web Application Firewall
3+
4+
[agent]
5+
name = "sentinel-agent-waf"
6+
version = "0.1.0"
7+
description = "Web Application Firewall agent for Sentinel reverse proxy - SQL injection, XSS, and attack detection"
8+
authors = ["Sentinel Contributors"]
9+
license = "MIT OR Apache-2.0"
10+
repository = "https://github.com/raskell-io/sentinel-agent-waf"
11+
12+
[protocol]
13+
version = "0.1"
14+
events = ["request_headers"]
15+
16+
[compatibility]
17+
sentinel-proxy = ">=0.1.0"
18+
sentinel-agent-protocol = "0.1"
19+
20+
[registry]
21+
homepage = "https://sentinel.raskell.io/agents/waf"
22+
documentation = "https://sentinel.raskell.io/docs/agents/waf"
23+
keywords = ["sentinel", "agent", "waf", "security", "sqli", "xss"]
24+
categories = ["security"]

0 commit comments

Comments
 (0)