143 lines
11 KiB
Markdown
143 lines
11 KiB
Markdown
# Threat model
|
|
|
|
## Scope en assets
|
|
|
|
Te beschermen:
|
|
|
|
- gebruikersaccount, sessies en zoekvoorkeuren;
|
|
- mailbox-, SMTP-, database- en registrycredentials;
|
|
- sollicitatiedossiers, notities en eventuele documenten;
|
|
- integriteit van vacatureclusters, scores en feedback;
|
|
- beschikbaarheid van de Unraid-host en het thuisnetwerk;
|
|
- bronbeleid en bewijs dat alleen toegestane bronnen worden benaderd.
|
|
|
|
Niet vertrouwd:
|
|
|
|
- iedere vacaturetekst, HTML, JSON-LD, feed en e-mail;
|
|
- alle links en redirectdoelen;
|
|
- externe DNS/HTTP/TLS-responses;
|
|
- AI-modeloutput, ook lokaal;
|
|
- browserinput en handmatige URL's;
|
|
- logs of exports die buiten de applicatie worden geopend.
|
|
|
|
## Trust boundaries
|
|
|
|
```text
|
|
Internet/mailbox
|
|
-> URL/source policy + IMAP boundary
|
|
-> raw document quarantine/retention
|
|
-> parser + sanitizer
|
|
-> normalized domain model
|
|
-> deterministic rules/scoring
|
|
-> authenticated UI / digest
|
|
|
|
User browser
|
|
-> TLS/reverse proxy
|
|
-> Django session + CSRF + object scoping
|
|
-> database
|
|
|
|
Django/Celery
|
|
-> Redis (queue, geen waarheid)
|
|
-> PostgreSQL (bron van waarheid)
|
|
-> optionele Ollama boundary
|
|
```
|
|
|
|
## Belangrijkste dreigingen en mitigaties
|
|
|
|
| ID | Dreiging | Impact | Mitigaties | Verificatie |
|
|
|---|---|---|---|---|
|
|
| T-01 | SSRF via bron- of vacature-URL | toegang tot LAN, metadata of beheerinterfaces | schema/host/IP/poortcontrole, DNS-resolutie, redirecthercontrole, denylist, geen credentials in URL | `tests/security/test_url_security.py`, `test_policy.py`, fetchertests |
|
|
| T-02 | DNS rebinding/tijd-van-controle | request bereikt ander IP dan beoordeeld | iedere fetch en redirect valideert opnieuw DNS-resolutie en vereist consistente IP-set-overlap | `VR-115`, `tests/unit/test_fetcher.py`, aanvullende fetcher negative tests |
|
|
| T-03 | XSS/HTML-injectie | sessiediefstal of ongewenste navigatie | Bleach allowlist, platte tekst, template autoescaping, CSP/securityheaders | `tests/security/test_sanitize.py`, viewtests |
|
|
| T-04 | Prompt injection in vacature | AI verandert beleid of voert tools uit | vacaturetekst in data-envelope, schema-output, evidence-validatie, cachefouten met foutcategorie, geen toolrechten, deterministische harde regels, AI optioneel | AI-tests, ADR-0003, `VR-109` evaluaties |
|
|
| T-05 | Malafide/oversized document | geheugen/CPU/diskuitputting | contenttype-, byte-, timeout- en redirectlimieten; korte retentie | fetchertests, source-runmetrics |
|
|
| T-06 | Crawlstorm of ban | externe overlast, IP-blokkade | expliciet allowbeleid, per-origin minimuminterval, concurrencylimiet, leasegebaseerde taakclaim met TTL + crash recovery, conditional requests, backoff, quarantaine | tasktests; `VR-103`, `VR-112` |
|
|
| T-07 | Direct platformscrapen | voorwaarden-/blokkaderisico | centrale denylist, e-mailingress, geen loginbot/CAPTCHA | policytests, ADR-0002/0005 |
|
|
| T-08 | E-mailparserlink naar phishing/private host | ongewenste fetch of gebruiker misleid | linkextractie slaat unsubscribe over, follow-up opnieuw door policy/SSRF, bronlabel zichtbaar | e-mail- en policytests |
|
|
| T-09 | MIME/HTML-bom of malformed mail | resource-uitputting/parsercrash | IMAPbatchlimiet, bodylimiet bij vervolgtaak, robuuste parser, idempotente recordidentiteit | `VR-115`, e-mailfixtures |
|
|
| T-10 | Cross-user objecttoegang | lek van sollicitaties/feedback | LoginRequired, user-scoped querysets/get_or_create, autorisatietests | integratie-viewtests |
|
|
| T-11 | CSRF op feedback/profiel | ongewenste status- of profielmutatie | Django CSRF-middleware, POST-only acties, SameSitecookies | viewtests en frameworkcheck |
|
|
| T-12 | Credentiallek in Git/logs | account- of infrastructuurcompromis | env-only secrets, gitignore, beperkte logs, voorbeeldwaarden, secretrotatierunbook | CI-secret scan gepland `VR-115`; review |
|
|
| T-13 | Onveilige reverse proxy | sessie over HTTP, host-header-/originproblemen | TLS, exact ALLOWED_HOSTS/CSRF origins, secure cookies, proxychecklist | deployment smoke-test |
|
|
| T-14 | Redis als waarheid behandeld | dataverlies/dubbele verwerking | PostgreSQL-state, idempotente taken/outbox, acks-late | integratietests |
|
|
| T-15 | Dubbele Celery-uitvoering | dubbele vacatures/mails | unieke keys, transacties, message identity, outbox-uniciteit | pipeline/digesttests |
|
|
| T-16 | Dedupe voegt verschillende jobs samen | gemiste kans/verkeerde data | exact vóór fuzzy, conservatieve drempel, bronaliassen/provenance, herstelbare clusterbeslissing gepland | dedupetests; `VR-116` evaluaties |
|
|
| T-17 | AI hallucineert ontbrekend feit | foutieve ranking | onbekend blijft onbekend, evidence/confidence, geen hard exclusion door AI | scoring/AI-tests |
|
|
| T-18 | Feedback poisoning/self-reinforcement | steeds smallere resultaten | begrensde gewichten, opt-in standaard uit, per-feature minimum samples, metadata-logging en resetpad | profieltests; `VR-110` |
|
|
| T-19 | Automatisch solliciteren/massamail | reputatie/privacy/juridisch risico | geen submitendpoint/task, expliciete ADR en non-goal | codezoekreview, AC-043 |
|
|
| T-20 | Kwaadaardig bestand in sollicitatiedossier | host/browsercompromis | uploads nog niet actief; vóór implementatie allowlist, sniffing, size limit, niet-uitvoerbare opslag vereist | `VR-113`, nieuwe threat review |
|
|
| T-21 | Back-up bevat secrets/PII | langdurig datalek | encryptie, gescheiden opslag, korte retentie, herstelprocedure | runbook en hersteltest |
|
|
| T-22 | Supply-chainpackage/image | code execution | exacte versies/lockfile, beperkte dependencies, pinned baseimages/digests en scans gepland | CI, `VR-115` |
|
|
| T-23 | Onbevoegde admin op thuisnetwerk | volledige datatoegang | uniek wachtwoord, TLS/VPN, geen defaultcredentials, sessiebeveiliging | Unraidchecklist |
|
|
| T-24 | Source terms wijzigen | ongewenste voortgezette crawling | reviewdatum, source health en policy expiry gepland | `VR-102`, `VR-112` |
|
|
| T-31 | Sollicitatiedossier-export bevat niet-gewenste payload | data-lek of onbedoeld dossieroverdragen | export bevat alleen het gekozen dossier, ZIP-inhoud is beperkt tot snapshot/tijdlijn/print-HTML, bestandsnaam is geslugified zonder padseparators | `tests/integration/test_applications.py` |
|
|
| T-32 | XML external entity/entity-expansion via sitemap | lokale data-uitlezing of parseruitputting | sitemap-XML wordt met `defusedxml` verwerkt; fetcherlimieten blijven vóór parsing gelden | `tests/unit/test_discovery_rss.py`, Ruff securitycheck |
|
|
| T-33 | Externe UI-CDN of niet-vertrouwde Stitch-interactie | supply-chain-XSS, tracking of acties buiten Django-beleid | productie gebruikt alleen lokale CSS/JS en inline SVG-symbolen; Stitch-code is documentatiereferentie, alle mutaties blijven Django POST+CSRF; themavoorkeur bevat geen persoonsgegevens en opslagfouten worden afgevangen | `tests/e2e/test_vr114_browser_and_accessibility.py`, browserconsole- en assetcontrole VR-118 |
|
|
|
|
## Misbruikscenario's
|
|
|
|
### Vacature zegt “negeer eerdere instructies”
|
|
|
|
De tekst wordt gesanitized en als veldwaarde doorgegeven. Een eventuele AI-call krijgt een vast schema en geen tools. De output kan geen bron activeren, URL openen, harde regel verwijderen, mail sturen of sollicitatie indienen.
|
|
|
|
### Publieke pagina redirect naar `192.168.1.1`
|
|
|
|
De redirectlocatie wordt opnieuw gevalideerd. Het request naar het private adres wordt niet uitgevoerd; de bronrun krijgt een policy/securityfout en de bron kan in quarantaine gaan.
|
|
|
|
### E-mailalert bevat een platformlink en uitschrijflink
|
|
|
|
De adapter herkent vacaturekandidaten, negeert bekende unsubscribepatronen en slaat de platformlink hoogstens als alias op. Automatisch volgen vereist opnieuw een toegestane source policy; denylistplatformen worden geweigerd.
|
|
|
|
### Aanvaller laat scheduler dezelfde job herhalen
|
|
|
|
Canonieke sleutels, databaseconstraints, transacties, idempotente message identity en outboxuniciteit beperken duplicaten. Taken zijn ontworpen voor at-least-once in plaats van exact-once aannames.
|
|
|
|
## Security gates bij nieuwe functionaliteit
|
|
|
|
Een wijziging aan netwerk, mail, AI, rendering, auth, exports of uploads vereist:
|
|
|
|
1. nieuwe/gewijzigde threat in deze tabel;
|
|
2. negatieve test die de aanval representeert;
|
|
3. begrensde input/output en foutcategorie;
|
|
4. logreview op secrets/PII;
|
|
5. runbook- en configuratie-update;
|
|
6. volledige `codex_verify`-gate.
|
|
|
|
## Resterende risico's
|
|
|
|
- Een applicatielaag kan DNS rebinding niet volledig uitsluiten zonder transportniveau-IP-pinning; dit staat in `VR-115`.
|
|
- Brute-force of herhaalde foutieve mutatiepogingen blijven mogelijk, maar zijn beperkt door in-memory rate limiting en blokkades op login/manual-import.
|
|
- Bronvoorwaarden vereisen menselijke/externe review per domein; automatisering kan dat niet juridisch beslissen.
|
|
- Fuzzy dedupe en featureheuristieken kunnen inhoudelijk verkeerd zijn; provenance, feedback en benchmarkevaluaties beperken maar elimineren dit niet.
|
|
- Een persoonlijke Unraid-host blijft afhankelijk van correcte netwerksegmentatie, patching en back-ups door de beheerder.
|
|
|
|
- T-25: Verloren of verlopen policyreview
|
|
- Impact: bron kan op onbedoelde wijze doorgaan met crawlen
|
|
- Mitigatie: `SourcePolicyReview` met decision/expiry + policy gate in `assess_url`
|
|
- Verificatie: security/integration tests rond verlopen review in fail-closed gedrag
|
|
|
|
- T-26: Handmatige URL/tekstimport
|
|
- Impact: ongewild ophalen van geblokkeerde of niet-ingesteste informatie, XSS via ingevulde tekst of overschrijding van limieten
|
|
- Mitigatie: CSRF-only import endpoint, allowlist-domeinvrije policy checks, sanitize op tekstveld, byte-limiet en max-size/timeout gedrag
|
|
- Verificatie: integration/security tests rond rejectie van geblokkeerde URL's en overschrijding van paste-limiet
|
|
|
|
- T-27: Reminder-flood of dubbele reminder-mails
|
|
- Impact: gebruiker ontvangt herhaalde of ongewenste herinneringen
|
|
- Mitigatie: stabiele `dedupe_key`, idempotente outbox met statusmachine, `reminder_type`-types en task-driven verzending
|
|
- Verificatie: `tests/integration/test_reminders.py`
|
|
|
|
- T-28: Onterecht verzenden zonder ontvanger/uitgeschakelde reminderinstelling
|
|
- Impact: onnodige fout- of testmails, verwarring over afmeldgedrag
|
|
- Mitigatie: master- en topmatchschakelaar per profiel, `SKIPPED`-status bij lege ontvanger en foutlogica met retries op taakniveau
|
|
- Verificatie: `tests/integration/test_reminders.py`
|
|
|
|
- T-29: Bronhealth zet bronnen te vroeg in quarantaine bij incidentele netwerkruis
|
|
- Impact: tijdelijke uitval of incidentele bronfouten blokkeren een gezonde bron
|
|
- Mitigatie: duidelijke foutcategoriedrempels, gescheiden policy/security- en tijdelijke-foutlogica, en canaryherstel via trialpad
|
|
- Verificatie: `tests/integration/test_source_health.py`
|
|
|
|
- T-30: Geautomatiseerde canaryherstel blijft onbegrensd draaien
|
|
- Impact: herhaalde herstarts van dezelfde bron veroorzaken extra belasting
|
|
- Mitigatie: cooldown plus metadataflag voor eenmalige canary, en trialstatus met beperkte runtrigger
|
|
- Verificatie: `tests/integration/test_source_health.py`
|