WAF – Web Application Firewall

Von Boris Sander14. November 2025
WAF – Web Application Firewall

WAF – Web Application Firewall

„Die erste Verteidigungslinie. Oder das erste Ärgernis, je nach Perspektive."


Sinn & Zweck

Eine WAF sitzt vor deiner Webanwendung und filtert bösartigen Traffic heraus, bevor er die App erreicht. Sie ist wie ein Türsteher: Manche Gäste werden sofort abgewiesen, manche werden genauer überprüft, und nur die harmlosen kommen durch.

Internet
    │
    ↓
┌─────────────────┐
│      WAF        │ ← "Halt! Du siehst verdächtig aus."
│   (Filtering)   │
└────────┬────────┘
         │ Nur sauberer Traffic
         ↓
┌─────────────────┐
│   Application   │
└─────────────────┘

Deployment-Modelle

Cloud-basiert (WAF-as-a-Service)

User → CDN/Cloud WAF → Origin Server

Beispiele:
- AWS WAF + CloudFront
- Cloudflare WAF
- Akamai Kona
- Azure Front Door

Vorteile: Schnell, skaliert, DDoS-Schutz inklusive Nachteile: Traffic geht über Drittanbieter, Kosten

Appliance (On-Premise)

User → Load Balancer → WAF Appliance → Application

Beispiele:
- F5 BIG-IP ASM
- Fortinet FortiWeb
- Imperva SecureSphere

Vorteile: Volle Kontrolle, Compliance (Daten bleiben intern) Nachteile: Teuer, Management-Aufwand

Host-basiert

User → Server (WAF + App auf gleicher Maschine)

Beispiele:
- ModSecurity (Apache/Nginx)
- NAXSI (Nginx)

Vorteile: Günstig, einfach für kleine Deployments Nachteile: Ressourcenkonkurrenz, weniger Features


WAF-Anbieter

Cloud-Nativ

AnbieterStärkenAnmerkung
AWS WAFAWS-IntegrationManaged Rules, Bot Control
CloudflareEinfach, schnellFree Tier verfügbar
Azure WAFAzure-IntegrationApplication Gateway
GCP Cloud ArmorGCP-IntegrationDDoS + WAF
AkamaiEnterprise, CDNTeuer aber robust
FastlyDeveloper-friendlyEdge Computing

Enterprise Appliances

AnbieterStärken
F5 BIG-IPUmfassend, etabliert
ImpervaLeader im Gartner MQ
Fortinet FortiWebPreis-Leistung
BarracudaEinfache Verwaltung

Open Source

ToolBeschreibung
ModSecurityDer Klassiker, Core Rule Set
NAXSINginx-native, Whitelist-Ansatz
CorazaModSecurity-kompatibel, Go-basiert

ModSecurity & OWASP Core Rule Set

Installation (Nginx)

# ModSecurity für Nginx
apt-get install libmodsecurity3 libnginx-mod-security

# OWASP CRS
git clone https://github.com/coreruleset/coreruleset.git /etc/nginx/modsecurity/crs

# Nginx Config
load_module modules/ngx_http_modsecurity_module.so;

server {
    modsecurity on;
    modsecurity_rules_file /etc/nginx/modsecurity/main.conf;
}

OWASP Core Rule Set (CRS)

Das CRS ist eine Sammlung von generischen Regeln, die häufige Angriffe erkennen:

# CRS Kategorien
├── REQUEST-901-INITIALIZATION
├── REQUEST-905-COMMON-EXCEPTIONS
├── REQUEST-910-IP-REPUTATION
├── REQUEST-911-METHOD-ENFORCEMENT
├── REQUEST-912-DOS-PROTECTION
├── REQUEST-913-SCANNER-DETECTION
├── REQUEST-920-PROTOCOL-ENFORCEMENT
├── REQUEST-921-PROTOCOL-ATTACK
├── REQUEST-930-APPLICATION-ATTACK-LFI
├── REQUEST-931-APPLICATION-ATTACK-RFI
├── REQUEST-932-APPLICATION-ATTACK-RCE
├── REQUEST-933-APPLICATION-ATTACK-PHP
├── REQUEST-934-APPLICATION-ATTACK-GENERIC
├── REQUEST-941-APPLICATION-ATTACK-XSS
├── REQUEST-942-APPLICATION-ATTACK-SQLI
├── REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION
├── REQUEST-944-APPLICATION-ATTACK-JAVA
└── RESPONSE-9XX (Response filtering)

Beispiel-Regel

# SQL Injection Detection
SecRule ARGS "@detectSQLi" \
    "id:942100,\
    phase:2,\
    block,\
    capture,\
    t:none,t:urlDecodeUni,\
    msg:'SQL Injection Attack Detected via libinjection',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
    tag:'application-multi',\
    tag:'language-multi',\
    tag:'platform-multi',\
    tag:'attack-sqli',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/248/66',\
    tag:'PCI/6.5.2',\
    severity:'CRITICAL',\
    setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"

AWS WAF Konfiguration

Managed Rules

# AWS WAF mit Managed Rules
Resources:
  WebACL:
    Type: AWS::WAFv2::WebACL
    Properties:
      DefaultAction:
        Allow: {}
      Rules:
        - Name: AWSManagedRulesCommonRuleSet
          Priority: 1
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesCommonRuleSet
          OverrideAction:
            None: {}
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: CommonRules
            
        - Name: AWSManagedRulesSQLiRuleSet
          Priority: 2
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesSQLiRuleSet
          OverrideAction:
            None: {}
          VisibilityConfig:
            SampledRequestsEnabled: true
            CloudWatchMetricsEnabled: true
            MetricName: SQLiRules

Custom Rules

# Rate Limiting
- Name: RateLimitRule
  Priority: 0
  Statement:
    RateBasedStatement:
      Limit: 1000
      AggregateKeyType: IP
  Action:
    Block: {}
  VisibilityConfig:
    SampledRequestsEnabled: true
    CloudWatchMetricsEnabled: true
    MetricName: RateLimit

# Geo-Blocking
- Name: BlockCountries
  Priority: 3
  Statement:
    GeoMatchStatement:
      CountryCodes:
        - RU
        - CN
        - KP
  Action:
    Block: {}

Was WAF erkennt (und was nicht)

Gut erkannt ✓

AngriffErkennungsmethode
SQL InjectionPattern Matching, libinjection
Cross-Site ScriptingPattern Matching
Path TraversalPattern Matching
Protocol ViolationsRFC Compliance Checks
Known CVE ExploitsSignature Matching
Bot TrafficBehavioral Analysis
DDoS (Layer 7)Rate Limiting

Schwer erkannt ⚠️

AngriffProblem
Business Logic FlawsKein Kontext über Business-Logik
Zero-Day ExploitsKeine bekannte Signatur
Low-and-Slow AttacksUnter Schwellenwerten
Credential StuffingValide HTTP-Requests
Authenticated AttacksNach Login ist Angreifer "trusted"

Bypassable 🚨

# WAF sieht: SELECT → Block!
# Angreifer versucht:

SeLeCt                    # Case Variation
SEL/**/ECT               # Comment Injection
%53%45%4c%45%43%54       # URL Encoding
CONCAT('SEL','ECT')      # String Concatenation

WAF ist keine Silver Bullet!


WAF-Modi

Detection Mode (Logging only)

mode: detection

behavior:
  - Log all requests
  - Score potential attacks
  - No blocking
  
use_case:
  - Initial deployment
  - Tuning phase
  - Risk assessment

Prevention Mode (Blocking)

mode: prevention

behavior:
  - Block malicious requests
  - Return 403 or custom page
  - Log blocked requests
  
use_case:
  - Production after tuning
  - High-risk applications

Paranoia Levels (CRS)

# Level 1: Minimal False Positives
paranoia_level: 1
# Erkennt: Offensichtliche Angriffe
# False Positives: Sehr wenige

# Level 2: Moderate
paranoia_level: 2
# Erkennt: Mehr Angriffsarten
# False Positives: Einige

# Level 3: Aggressive
paranoia_level: 3
# Erkennt: Subtile Angriffe
# False Positives: Viele

# Level 4: Maximum Paranoia
paranoia_level: 4
# Erkennt: Alles Verdächtige
# False Positives: Sehr viele (Tuning-Albtraum)

Tuning & False Positives

Das Problem

User Upload: Blogpost über SQL-Datenbanken
Content: "To query data, use SELECT * FROM..."

WAF: "SQL INJECTION! BLOCK!"
User: "Aber das ist mein Tutorial!"

Lösungsstrategien

1. Regel-Ausnahmen (Rule Exclusions):

# CRS: Bestimmte Regel für Pfad deaktivieren
SecRule REQUEST_URI "@beginsWith /api/code-examples" \
    "id:1,phase:1,nolog,pass,\
    ctl:ruleRemoveById=942100"

2. Whitelist für Parameter:

# Parameter von SQL-Checks ausnehmen
SecRule ARGS:code_snippet "@rx .*" \
    "id:2,phase:2,nolog,pass,\
    ctl:ruleRemoveTargetById=942100;ARGS:code_snippet"

3. Anomaly Scoring Threshold:

# Höheren Threshold für bestimmte Pfade
SecRule REQUEST_URI "@beginsWith /admin" \
    "id:3,phase:1,nolog,pass,\
    setvar:tx.inbound_anomaly_score_threshold=25"

4. Learning Mode:

# Cloudflare: Learning aktivieren
learning_mode:
  enabled: true
  duration: 7 days
  then: generate_exceptions

Best Practices

1. Staging zuerst

Dev → Staging (WAF Detection) → Staging (WAF Blocking) → Prod

2. Logging aktivieren

logging:
  enabled: true
  include:
    - matched_rules
    - request_headers
    - request_body  # Vorsicht bei PII!
    - client_ip
    - user_agent

3. Regelmäßig updaten

# CRS Updates
cd /etc/modsecurity/crs
git pull
nginx -t && systemctl reload nginx

4. Custom Rules für eigene App

# Beispiel: API Key in Header erforderlich
SecRule &REQUEST_HEADERS:X-API-Key "@eq 0" \
    "id:10001,phase:1,deny,status:401,\
    msg:'Missing API Key',\
    tag:'custom/api-security'"

5. Rate Limiting implementieren

# AWS WAF Rate Rule
RateBasedRule:
  Limit: 1000  # Requests pro 5 Minuten
  AggregateKeyType: IP
  Action: Block

6. Geo-Blocking erwägen

# Wenn dein Business nur DACH ist:
allow_countries:
  - DE
  - AT
  - CH
block_all_others: true  # Drastisch, aber effektiv

Monitoring & Alerting

Metriken

key_metrics:
  - blocked_requests_per_minute
  - top_blocked_rules
  - top_blocked_ips
  - false_positive_rate
  - attack_categories
  
alerts:
  - condition: blocked_requests > 1000/min
    action: page_oncall
    
  - condition: new_ip_blocked_count > 100
    action: investigate_ddos
    
  - condition: rule_942100_hits > 50/hour
    action: sqli_attack_in_progress

Dashboard

┌────────────────────────────────────────────────────────────┐
│                    WAF Dashboard                            │
├────────────────────────────────────────────────────────────┤
│ Requests Today: 1,247,892                                   │
│ Blocked: 12,456 (1.0%)                                     │
├────────────────────────────────────────────────────────────┤
│ Top Blocked Rules:                                          │
│ 1. 942100 - SQL Injection (libinjection): 5,234            │
│ 2. 941100 - XSS Attack (libinjection): 3,892               │
│ 3. 931100 - Path Traversal: 1,876                          │
├────────────────────────────────────────────────────────────┤
│ Top Blocked IPs:                                            │
│ 1. 185.x.x.x (Russia) - 2,345 blocks                       │
│ 2. 45.x.x.x (VPN) - 1,234 blocks                           │
│ 3. 103.x.x.x (China) - 987 blocks                          │
└────────────────────────────────────────────────────────────┘

WAF + Defense in Depth

                    ┌─────────────────┐
                    │      CDN        │ ← DDoS Mitigation
                    │   (Edge Cache)  │
                    └────────┬────────┘
                             │
                    ┌────────┴────────┐
                    │       WAF       │ ← Layer 7 Filtering
                    │                 │
                    └────────┬────────┘
                             │
                    ┌────────┴────────┐
                    │  Load Balancer  │ ← SSL Termination
                    │                 │
                    └────────┬────────┘
                             │
                    ┌────────┴────────┐
                    │   Application   │ ← RASP, Secure Code
                    │     (+ RASP)    │
                    └────────┬────────┘
                             │
                    ┌────────┴────────┐
                    │    Database     │ ← Query Parameterization
                    │                 │
                    └─────────────────┘

Risiken & Grenzen

False Positives = Business Impact

Legitimer User blockiert → Lost Sale
API Integration blockiert → Partner wütend
Googlebot blockiert → SEO Katastrophe

False Negatives = Security Impact

WAF umgangen → Breach
Neue Angriffstechnik → Zero Day

Performance

WAF Latency: 1-10ms pro Request
Bei 10.000 req/s = zusätzliche Last

Operational Burden

Regeln pflegen
False Positives tunen
Updates einspielen
Incidents untersuchen

Fazit

Eine WAF ist eine wichtige Verteidigungsschicht, aber keine Wunderwaffe. Sie filtert das Offensichtliche heraus und kauft Zeit für bessere Fixes im Code. Aber sie ersetzt keinen sicheren Code, keine Penetration Tests und keine Security-Awareness.

Eine WAF ist wie ein Türsteher: Sie hält die offensichtlichen Troublemaker draußen, aber ein entschlossener Angreifer mit VIP-Pass (valider Session) kommt trotzdem rein.


Weiterführende Ressourcen: