113 lines
4.1 KiB
Markdown
113 lines
4.1 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.
|
|
|
|
Webfetches, robotsrequests en IMAP-TLS gebruiken expliciet de bij de release vastgelegde `certifi`-CA-bundel. Hostnaamcontrole en `CERT_REQUIRED` blijven verplicht. Een verouderde Windows-rootstore is daarom geen reden voor `verify=False`; werk de gepinde bundel en lockfile gecontroleerd bij en voer de TLS-negatietests opnieuw uit.
|
|
|
|
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
|
|
|
|
- een dedicated mailbox per platform;
|
|
- attachments worden genegeerd;
|
|
- message identity voorkomt dubbele verwerking;
|
|
- platformgebonden import accepteert alleen gelabelde HTTPS-links op het expliciet gekozen jobboarddomein;
|
|
- externe tracking-, account-, help-, privacy- en uitschrijflinks worden niet als vacature opgeslagen;
|
|
- links worden niet automatisch gevolgd tenzij later door bronpolicy goedgekeurd;
|
|
- mailbox-app-wachtwoorden versleuteld in de database met een afzonderlijke, roteerbare environmentkey;
|
|
- 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.
|