-
Notifications
You must be signed in to change notification settings - Fork 0
Pentest 2026 07 14
mdeguzis edited this page Jul 14, 2026
·
3 revisions
Initial comprehensive manual security audit of proton-pulse-web covering auth, RLS, XSS, edge functions, and the data pipeline.
- All client-side JavaScript (app pages, shared libs, search, game pages)
- Supabase Edge Functions (steam-callback, plugin-link, steam-appdetails, etc.)
- Supabase RLS policies (all migration files)
- Data pipeline Python scripts
- GitHub Actions workflows
- OWASP Top 10 (2021)
- OWASP Application Security Verification Standard (ASVS) v4.0
- CWE/SANS Top 25 Most Dangerous Software Weaknesses
- OWASP Cheat Sheet Series
- MDN Content Security Policy reference
- Supabase Security Best Practices
| # | Severity | Finding | CWE/Standard | Fix applied | Issue |
|---|---|---|---|---|---|
| 1 | CRITICAL | Weak password derivation (8 chars of service key + public Steam ID) | CWE-916: Use of Password Hash With Insufficient Computational Effort | HMAC-SHA256 with full key per OWASP Password Storage Cheat Sheet | #291 |
| 2 | HIGH | No Content Security Policy | CWE-1021: Improper Restriction of Rendered UI Layers | CSP meta tag per OWASP CSP Cheat Sheet | #292 |
| 3 | HIGH | No rate limiting on public edge function proxies | CWE-770: Allocation of Resources Without Limits | Per-IP rate limiting per OWASP Rate Limiting guidance | #293 |
| 4 | HIGH | report_approvals RLS grants all authenticated users write access | CWE-862: Missing Authorization | Revoked grants, admin-only policy per OWASP Access Control Cheat Sheet | #294 |
| 5 | HIGH | Delete operations use anon key instead of user session token | CWE-306: Missing Authentication for Critical Function | Bearer token from user session per OWASP AuthN Cheat Sheet | #295 |
| 6 | MEDIUM | renderPermalink appId interpolation without JS-escaping | CWE-79: Cross-site Scripting (XSS) | Input escaped for JS string context per OWASP XSS Prevention Cheat Sheet | #296 |
| 7 | MEDIUM | plugin-link-start no auth, no rate limiting | CWE-307: Improper Restriction of Excessive Authentication Attempts | 10 req/IP/min rate limit | #297 |
| 8 | MEDIUM | markdown-it linkify missing rel="noopener noreferrer" | CWE-1022: Use of Web Link to Untrusted Target with window.opener Access | Added via renderer rule per MDN rel=noopener | #298 |
Audit covered:
- Auth flow trace from Steam OpenID through token issuance and session storage
- API key inventory (confirmed only anon/publishable keys in client code)
- XSS vector search across all innerHTML usage and template interpolation
- RLS policy review for every table in the migration history
- Edge function analysis for auth bypass, input validation, and rate limiting
- Privacy data inventory (what is stored, retention)
- CSP and security headers check
- Dependency audit (package.json, pip deps)
- Data pipeline input sanitization (subprocess calls, API response handling)
- HTML escaping via
esc()function uses the DOM textContent/innerHTML pattern (OWASP XSS Rule #1) - No service role keys in client code (only anon key, per Supabase client-side auth docs)
- Open redirect mitigated via origin validation (CWE-601 addressed)
- PostgREST parameterized queries prevent SQL injection (CWE-89 not applicable)
- subprocess.run uses list args, not shell=True (CWE-78 not applicable)
- Session token stripped from URL hash immediately via history.replaceState (per OWASP Session Management Cheat Sheet)
- markdown-it html:false blocks raw HTML injection in user notes
All 8 findings were fixed in the same session as the audit (2026-07-14). Fixes are on the staging branch pending review and production deploy. The password derivation migration is backward-compatible: returning users are transparently migrated to the stronger HMAC on their next login.