Files
VacatureRadar/docs/architecture/SECURITY_ARCHITECTURE.md
T
Jens b8091e59bd
deploy / deploy (push) Canceled after 0s
Initial deploy setup
2026-07-21 14:00:00 +02:00

109 lines
3.5 KiB
Markdown

# Securityarchitectuur
## 1. Principes
- fail closed voor bronpolicy en URL-validatie;
- least privilege voor containers en credentials;
- externe inhoud is data;
- menselijke bevestiging voor impactvolle externe acties;
- korte retentie en beperkte evidence;
- defense in depth: sanitization + CSP + outputescaping;
- idempotentie en audit boven verborgen magie.
## 2. Netwerkpad
Alle automatische publieke HTTP(S)-requests lopen via `apps.sources.services.fetcher.fetch_url`.
Verplichte stappen:
1. `assess_url`: hostname + denylist + source policy/status;
2. `validate_public_url`: schema, credentials, hostname, poort, DNS, alle IP's global;
3. request zonder automatische redirects;
4. ieder redirectdoel opnieuw door policy en URL-validatie;
5. response status/contenttype/grootte controleren;
6. alleen allowlisted headers bewaren.
Geen adapter of view mag dit pad omzeilen.
## 3. SSRF
Geblokkeerd:
- localhost en `.localhost`;
- IPv4/IPv6 loopback, private, link-local, multicast, unspecified en niet-global;
- embedded credentials;
- non-HTTP(S);
- niet-standaardpoorten tenzij expliciet geconfigureerd;
- redirect naar geblokkeerd doel.
Resterend risico: klassieke DNS rebinding tussen resolutie en socketconnectie. Productiehardening moet connectie-IP pinning of een outbound proxy/egress firewall toevoegen. Tot die tijd hoort de container geen toegang te hebben tot gevoelige interne control planes.
## 4. Webbeveiliging
- Django authentication en user-scoped querysets;
- CSRF-middleware op mutaties;
- secure/HttpOnly/SameSite cookies in productie;
- HSTS en SSL redirect achter correct geconfigureerde proxy;
- `X-Frame-Options: DENY` en CSP `frame-ancestors 'none'`;
- content type nosniff, strict referrer, beperkte permissions policy;
- geen externe scripts/fonts in kerninterface;
- vacature-HTML door Bleachallowlist vóór opslag/rendering.
## 5. E-mail
- dedicated mailbox;
- attachments worden genegeerd;
- message identity voorkomt dubbele verwerking;
- links worden niet automatisch gevolgd tenzij later door bronpolicy goedgekeurd;
- mailboxcredentials alleen environment/secret;
- raw mail korte retentie;
- log geen volledige onderwerp/body wanneer daarin PII kan staan.
## 6. AI
- opt-in en lokaal als defaultarchitectuur;
- vacaturetekst expliciet onbetrouwbare data;
- geen tools/function calling;
- gestructureerd schema en temperatuur 0;
- maximaal inputvolume;
- outputvalidatie en deterministische fallback;
- model-/promptversie opslaan;
- AI-container hoeft geen internettoegang.
## 7. Secrets
Minimaal:
- Django secret key;
- databasepassword;
- adminpassword bootstrap;
- IMAP/SMTPcredentials;
- eventueel reverse-proxy/OIDC secrets.
Regels:
- `.env` is gitignored en mode 600;
- geen secrets in Composebestand, fixtures, screenshots of docs;
- productie gebruikt Unraid secrets/configpad met beperkte rechten;
- rotatie na lek of restore naar onvertrouwde host;
- back-ups van config/secrets apart versleutelen.
## 8. Containerhardening (productietaak)
Aanbevolen:
- non-root runtimeuser;
- read-only root filesystem waar haalbaar;
- `no-new-privileges`;
- capabilities drop all;
- tmpfs voor `/tmp` en Celery beatschedule;
- resource limits;
- database/Redis niet publiceren;
- apart egressnetwerk/proxy;
- immutable image digest;
- dependency/image scanning.
## 9. Audit
Bronruns, vacatureversies, score runs, feedback en outbox vormen de functionele audittrail. Securityauditlogs moeten aanvullend login-/policy-/quarantainewijzigingen opnemen zonder vacaturetekst of secrets.