PlusMin BudgetScanner
Project: PlusMin BudgetScanner
Status: High-Security Web Implementation (Production Grade)
Architectuur: React (Vite) + MUI v6 + Nginx (OpenResty/NPM)
Laatste Audit: 07 April 2026 (npm audit: 0 vulnerabilities)
1. Executive Summary
De PlusMin BudgetScanner hanteert een model voor lokale financiële dataverwerking zonder opslag en met strikte verificatie . De beveiliging rust op drie pijlers: transportbeveiliging (HSTS Preload, HTTP/2 en redirect naar https://), autorisatie van resources via dynamische nonces, en de volledige eliminatie van client-side opslag. Dit rapport beschrijft de mitigatie van XSS, data-exfiltratie en sessie-gebaseerde aanvallen.
2. Functionaliteit
De BudgetScanner is een web applicatie waarmee gebruikers banktransacties, bij voorkeur over een heel jaar, kunnen uploaden en categoriseren. Transacties worden geëxporteerd vanuit de bank als CSV- of CAMT.053-bestand (xml). De categorisatie bestaat uit het koppelen van transacties aan potjes, het kernconcept van de PlusMin-methode.
Alle verwerking vindt volledig client-side plaats in de browser. De applicatiestate kan tussentijds lokaal worden opgeslagen als JSON-bestand, met daarin alle transacties, potjes en de relaties daartussen. Door dit bestand opnieuw te importeren, hervat de gebruiker de categorisatie op het moment van opslaan.
Als eindresultaat kan een PDF-rapport worden gegenereerd met een samenvatting van de in- en uitgaven per potje, uitgesplitst per maand. De applicatie is daarmee bij uitstek geschikt als eerste stap in het traject voor financiële ondersteuning, waarbij de inventarisatie gestructureerd en versneld wordt ingevuld.
3. Security Design Principles
3.1 Transport Security & Protocol Hardening
De integriteit van de BudgetScanner is inherent verbonden met een beveiligde verbinding. De infrastructuur dwingt dit af op drie gelaagde niveaus via de Nginx Proxy Manager (NPM):
- Server-side Force SSL (301 Redirect): De proxy is geconfigureerd om alle inkomende HTTP-verzoeken onmiddellijk via een
301 Moved Permanentlystatuscode om te leiden naar HTTPS. Dit garandeert dat de initiële verbinding altijd wordt getransformeerd naar een beveiligde tunnel. - HSTS Policy (Browser-side Lock): Ter versterking wordt de header
Strict-Transport-Security "max-age=31536000; includeSubDomains"meegegeven. Hiermee dwingt de browser bij vervolgbezoeken zelfstandig HTTPS af (Client-side Redirect), nog voordat er contact met de server is gemaakt. Dit elimineert de kwetsbaarheid voor SSL-stripping aanvallen en beschermt de cryptografische nonces in de HTML-stroom tegen interceptie. - HTTP/2 Protocol Support: Door de activatie van HTTP/2 wordt niet alleen de performance van de vele gehashte JavaScript-chunks verbeterd, maar wordt ook het gebruik van moderne, veilige cipher suites afgedwongen. Dit minimaliseert het risico op aanvallen die gericht zijn op verouderde TLS-implementaties.
3.2 Dynamic Nonce Injection & Resource Integrity
De BudgetScanner gebruikt een unieke identifier per verzoek om inline stijlen en scripts te autoriseren zonder de veiligheid van de CSP te verzwakken.
- Mechanism: Nginx genereert een
$request_iddie via desub_filtermodule in de HTML wordt geïnjecteerd (window.__csp_nonce__). - Betrouwbaarheid: Om de fragiliteit van tekstvervanging in Nginx te beperken, is
proxy_bufferingen compressie op de proxy-layer uitgeschakeld. Dit garandeert dat de placeholder (%%CSP_NONCE%%) consistent wordt vervangen. - Asset Hashing & Resource Integrity: Alle statische assets (JS/CSS) worden geadresseerd via content-hashes in bestandsnamen. Dit maakt onbedoelde wijzigingen direct zichtbaar in deployment- en cachegedrag en voorkomt dat oude assets stilzwijgend worden hergebruikt. Dit mechanisme is sterk voor integriteit op build/deploy-niveau.
3.3 Content Security Policy (CSP) Directives
De browser dwingt de volgende policy af:
default-src 'self'; script-src 'self' 'nonce-ID'; style-src 'self' 'nonce-ID'; img-src 'self' data:; font-src 'self';
- Exfiltratie-blokkade: Door het ontbreken van externe domeinen in de
connect-src(viadefault-src), kan de browser onder geen beding data verzenden naar derden, zelfs niet bij een hypothetische script-injectie.
3.4 Zero-Persistence & Data Volatility
De applicatie is ontworpen om geen forensische sporen achter te laten:
- Geen Cookies: Elimineert het risico op Session Hijacking en CSRF.
- Geen Storage: Geen gebruik van
localStorage,sessionStorageofIndexedDB. Gevoelige data bevindt zich uitsluitend in het vluchtige RAM-geheugen van de actuele tab. - Functionaliteit: Bij het sluiten van de tab of een browser-crash wordt de dataset direct vernietigd.
4. Applicatie Integriteit & Supply Chain
4.1 Data Parsing Security
De verwerking van bankbestanden (CSV en CAMT.053 XML) vindt volledig plaats binnen de browser-sandbox.
- XML Safety: Er wordt gebruikgemaakt van browser-native parsers die bescherming bieden tegen XML External Entity (XXE) aanvallen door externe entiteiten standaard te blokkeren.
- Dependency Auditing: Het project voert controles uit op externe bibliotheken. De scan via
npm auditop 7 april 2026 resulteerde in 0 vulnerabilities. Het slagen van de scan is opgenomen als voorwaarde in het deployment script.
5. Risicoanalyse & Restrisico’s (Disclaimer)
Hoewel de architectuur robuust is, worden de volgende restrisico’s erkend:
- DOM-based XSS: De CSP en nonces beschermen tegen de injectie van externe scripts. De veiligheid tegen manipulatie van de bestaande pagina-inhoud blijft echter afhankelijk van strikte code-audits en het vermijden van onveilige React-patronen zoals
dangerouslySetInnerHTML. - Browser-Extensies (Client-Side Interceptie): Tijdens runtime kunnen aanroepen van het type
chrome-extension://in de netwerk-log voorkomen. Dit is een directe observatie van geïnstalleerde browser-extensies die assets (zoals lokalisatiebestanden of scripts) laden binnen de context van de applicatie.- Beperking: Omdat browser-extensies door het OS/Browser-model vaak privileges krijgen die buiten de CSP-sandbox vallen, kan de applicatie-architectuur niet beschermen tegen kwaadaardige software op extensie-niveau.
- Mitigatie: De impact van dit risico wordt gemitigeerd door het Stateless-model; er zijn geen persistente gevoelige data (cookies, tokens of localStorage) aanwezig die door extensies geëxtraheerd kunnen worden voor later gebruik.
- Fragiliteit van
sub_filter: De dynamische injectie van de nonce via Nginx is afhankelijk van de exacte match van tekststrings. Bij configuratiefouten in de upstream buffering zou de vervanging kunnen falen, wat leidt tot een functionele blokkade door de browser (veiligheidshalve).
6. Verificatiehandleiding voor Experts
A. Headers & Transport Audit
curl -I https://dev.plusmin.org/
Check: Verifieer de HSTS-header (inclusief preload) en de dynamische nonces in de CSP-header.
B. Storage & Leakage Audit
Inspecteer de browser DevTools (F12):
- Application Tab: Bevestig dat alle Storage-secties leeg blijven tijdens het gebruik.
- Network Tab: Bevestig dat er geen verbindingen buiten de eigen origin (
dev.plusmin.org) plaatsvinden.
C. Source Code Audit
- De code is gepubliceerd op https://github.com/orgs/plusminapp/repositories
- Controleer de
main.tsxop de correcte initialisatie van deCacheProvidermet de nonce, en verifieer in de Dockerfile dat er geen onnodige server-side componenten actief zijn. - Controleer de code op onveilige patronen zoals
dangerouslySetInnerHTML.
7. Conclusie
De BudgetScanner implementeert een hoog beveiligingsniveau door de browser te dwingen als een geïsoleerde, vluchtige zandbak te fungeren. De combinatie van transportbeveiliging en een volledig stateless model biedt maximale privacygaranties voor lokale financiële data.