A production-inspired, modular Web Application Firewall (WAF) implemented in Go. This WAF acts as a reverse proxy, inspecting and filtering HTTP requests based on configurable security rules before forwarding them to backend applications.
- Reverse Proxy: Forwards legitimate requests to upstream backend servers
- Rule Engine: Signature-based detection with regex, contains, and equals operators
- Anomaly Scoring: Each matched rule contributes to an anomaly score
- Decision Engine: Blocks requests when anomaly score exceeds threshold
- Request Normalization: URL decoding, path cleaning, query parameter normalization
- Structured Logging: JSON-formatted logs for all requests and decisions
- YAML Configuration: Easy-to-manage configuration files
- Modular Architecture: Clean, extensible codebase
- Go 1.21 or later
- A backend application to protect (optional, for testing)
- Clone the repository:
git clone https://github.com/yusufdalbudak/Advanced-Waf-Lab
cd WAF-DRAFT- Install dependencies:
go mod download- Run the WAF:
go run ./cmd/wafdThe WAF will start on port 8080 (configurable) and forward requests to http://localhost:8081 by default.
server:
listen_address: ":8080" # WAF listening address
upstream_url: "http://localhost:8081" # Backend server URL
read_timeout_seconds: 10
write_timeout_seconds: 10
idle_timeout_seconds: 60
security:
anomaly_threshold: 10 # Score threshold for blocking
log_request_bodies: false # Log request bodies (privacy consideration)
logging:
level: "info"
output: "stdout" # "stdout" or file path
rules:
files:
- "configs/ruleset.yaml" # Rule files to loadRules define conditions that, when matched, contribute to the anomaly score:
- id: "SQLI-001"
name: "Basic SQL Injection"
severity: 10
phase: "request"
enabled: true
tags: ["sqli", "injection"]
conditions:
- target: "query"
operator: "regex"
value: "(?i)(\\bor\\b\\s+1\\s*=\\s*1|union\\s+select)"
actions:
- type: "add_score"
param: 10- id: Unique rule identifier
- name: Human-readable rule name
- severity: Base severity score (0-100)
- phase: Request phase ("request" for now)
- enabled: Whether the rule is active
- tags: Categories for the rule (e.g., "sqli", "xss")
- conditions: List of match conditions (all must match - AND logic)
- actions: Actions to take when rule matches
path: URL pathquery: All query parametersheader: All headersbody: Request bodymethod: HTTP method
equals: Exact matchcontains: Substring match (case-insensitive)regex: Regular expression matchstarts_with: Prefix matchends_with: Suffix match
- Request Reception: HTTP request arrives at WAF server
- Normalization: Request is normalized (URL decode, path cleaning, etc.)
- Rule Evaluation: Detection engine evaluates request against all enabled rules
- Anomaly Scoring: Matched rules contribute to anomaly score
- Decision Making: Decision engine compares score to threshold
- Logging: Request and decision are logged in JSON format
- Mitigation:
- If blocked: Return 403 Forbidden
- If allowed: Forward to upstream via reverse proxy
The anomaly_threshold setting determines when requests are blocked:
- If
anomaly_score >= threshold→ BLOCK (403 Forbidden) - If
anomaly_score < threshold→ ALLOW (forward to upstream)
Each rule can contribute to the score via the add_score action. Multiple rules can match, and their scores are cumulative.
A request with SQL injection (?id=1 OR 1=1) might match:
- SQLI-001: +10 points
- SQLI-003: +8 points
- Total: 18 points
If threshold is 10, this request is blocked.
# Use default config
go run ./cmd/wafd
# Use custom config
go run ./cmd/wafd -config /path/to/config.yaml# Legitimate request (should be allowed)
curl http://localhost:8080/api/users?id=123
# SQL injection (should be blocked)
curl http://localhost:8080/api/users?id=1%20OR%201=1
# XSS attempt (should be blocked)
curl "http://localhost:8080/api/search?q=<script>alert('xss')</script>"The WAF logs all requests in JSON format:
{
"timestamp": "2024-01-15T10:30:45Z",
"source_ip": "127.0.0.1",
"method": "GET",
"path": "/api/users",
"status": 403,
"decision": {
"action": "block",
"reason": "Anomaly score 18 exceeds threshold 10",
"score": 18,
"matched_rules": ["SQLI-001", "SQLI-003"]
},
"request_id": "1705315845000000000-/api/users",
"user_agent": "curl/7.68.0",
"query_string": "id=1 OR 1=1"
}To add a new security rule:
- Edit
configs/ruleset.yaml - Add a new rule entry:
- id: "NEW-001"
name: "My New Rule"
severity: 8
phase: "request"
enabled: true
tags: ["custom"]
conditions:
- target: "query"
operator: "contains"
value: "malicious-pattern"
actions:
- type: "add_score"
param: 8- Restart the WAF (rules are loaded at startup)
go test ./test/integration/...go test -fuzz=FuzzNormalizePath ./test/fuzz/...
go test -fuzz=FuzzRuleMatching ./test/fuzz/...go test ./...waf/
├── cmd/
│ └── wafd/ # Main entrypoint
│ └── main.go
├── internal/
│ ├── config/ # Configuration loading
│ ├── normalize/ # Request normalization
│ ├── detection/ # Rule engine and detection
│ │ ├── rules/ # Rule definitions
│ │ ├── engine.go # Detection engine
│ │ └── anomaly.go # Anomaly scoring
│ ├── decision/ # Decision engine
│ ├── mitigation/ # Block/allow actions
│ ├── logging/ # Structured logging
│ ├── httpserver/ # HTTP server and handlers
│ └── telemetry/ # Metrics collection
├── configs/
│ ├── waf.yaml # Main configuration
│ └── ruleset.yaml # Security rules
├── test/
│ ├── integration/ # Integration tests
│ └── fuzz/ # Fuzz tests
├── docs/
│ ├── architecture.md # System architecture
│ ├── threat-model.md # Security threat model
│ └── waf-benchmark-plan.md # Benchmarking plan
└── README.md
- Architecture: Detailed system architecture and design
- Threat Model: Security analysis using STRIDE framework
- Benchmark Plan: Testing and benchmarking strategy
- Configuration Security: Protect configuration files with appropriate permissions
- Rule Updates: Regularly update rules to detect new attack patterns
- Logging: Be mindful of logging sensitive data (PII, credentials)
- Performance: Monitor performance impact, especially with complex regex rules
- False Positives: Tune anomaly threshold to balance security and usability
This is an MVP implementation. Future enhancements could include:
- Rate limiting
- IP whitelisting/blacklisting
- Request body size limits
- Advanced evasion detection
- Machine learning-based anomaly detection
- Real-time rule updates
- Distributed deployment
- Metrics dashboard
This is a draft/prototype implementation. Contributions and improvements are welcome!
- Inspired by ModSecurity and OWASP ModSecurity Core Rule Set (CRS)
- Built following OWASP WAF guidelines