# Functional Design Questions — U3 HTTP Security Headers & CSP Vul je keuze in achter elke `[Answer]:`-tag. Kies de laatste optie (`Anders`) als niets past. --- ## Question 1 — De admin-SPA gaat kapot van een echt strikte CSP **Context**: de admin-SPA gebruikt Radix UI-componenten (dialogen, dropdowns, selects) via shadcn-stijl wrappers. Die plaatsen positionering als **inline `style`-attributen** op elementen — dat is hoe een dropdown weet waar hij moet staan. Een CSP met `style-src 'self'` en zonder `'unsafe-inline'` blokkeert die inline styles. Het gevolg is niet een foutmelding maar verkeerd gepositioneerde of onzichtbare menu's en dialogen: kapot op een manier die je pas in de browser ziet, en pas op de plekken waar je klikt. Er zijn drie manieren om hiermee om te gaan: A) `style-src 'self' 'unsafe-inline'` in de strikte policy, met een gedocumenteerde onderbouwing waarom die uitzondering nodig is — pragmatisch en meteen werkend. `script-src` blijft wél strikt, en dat is waar XSS-risico echt zit B) Nonces of hashes gebruiken voor styles — theoretisch netter, maar Radix genereert styles op runtime per interactie, dus dit werkt in de praktijk niet zonder de componenten te herschrijven C) Begin met `Content-Security-Policy-Report-Only` voor `/admin`, kijk wat er daadwerkelijk overtreden wordt, en zet hem daarna afdwingend — niets breekt stil, maar de bescherming staat er in de tussentijd niet X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]: B --- ## Question 2 — Wat mag de publieke website? **Context**: je koos een ruimere CSP voor de publieke website (D-31), omdat een website-bouwer niet beperkt moet worden door een policy die hij nooit gezien heeft. Maar "ruimer" moet nog wel iets betekenen — de website wordt door hetzelfde proces geserveerd als de admin-UI en de API. A) Ruim maar niet leeg: sta scripts, styles, afbeeldingen en fonts van eigen origin plus inline toe, en verbindingen naar eigen origin plus de geconfigureerde origins. Externe scripts (bijv. een YouTube-embed) worden dan geblokkeerd tenzij toegevoegd B) Alleen de echt beschermende headers voor de website (`X-Content-Type-Options`, HSTS, `Referrer-Policy`) en **geen** CSP — dan kan een website-bouwer nooit verrast worden C) Ruim, plus in het website-contract vastleggen dat een bouwer extra origins kan laten toevoegen aan de configuratie als hij externe bronnen nodig heeft X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:B --- ## Question 3 — Gelden de headers ook lokaal? **Context**: `Strict-Transport-Security` vertelt de browser: gebruik voor dit domein voortaan altijd HTTPS. Browsers onthouden dat **per host, langdurig**. Stuur je die header op `localhost`, dan kan dat je lokale ontwikkeling van andere projecten op dezelfde `localhost` gaan dwarszitten, en het is niet triviaal om weer ongedaan te maken. De CSP lokaal wél actief hebben is juist nuttig: dan merk je een overtreding tijdens ontwikkelen in plaats van in productie. A) CSP en de overige headers ook in Development; **HSTS alleen buiten Development** — je ziet CSP-problemen vroeg, zonder je `localhost` te vervuilen B) Alle headers in alle omgevingen, inclusief HSTS lokaal C) Geen enkele header in Development — lokaal zo weinig ruis als mogelijk X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A --- ## Question 4 — Mag `/admin` in een iframe? **Context**: je koos `X-Frame-Options: DENY` in de requirements (FR-18). Dat betekent dat geen enkele pagina van dit domein in een iframe geplaatst mag worden — ook niet door de site zelf. Dat is voor de admin-UI precies goed. Maar het geldt dan ook voor de publieke website, en een klant die op zijn eigen site een pagina in een iframe toont (bijvoorbeeld een formulier of een kaart in een eigen iframe), loopt daar tegenaan. A) `DENY` voor `/admin` en `/api/v1`, `SAMEORIGIN` voor de publieke website — de admin-UI blijft maximaal beschermd, de website kan zijn eigen pagina's insluiten B) `DENY` overal, zoals in de requirements — en een klant die iframes nodig heeft, komt dan bij jou terecht C) `SAMEORIGIN` overal — eenvoudiger, iets minder strikt voor de admin-UI X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:A --- ## Question 5 — Wat als er geen origins geconfigureerd zijn? **Context**: de Umami- en Sentry-origins komen uit configuratie en verschillen per omgeving. In een omgeving zonder Sentry of Umami — bijvoorbeeld lokaal, of een instantie zonder analytics — zijn die lijsten leeg. Een strikte CSP zonder die origins is correcter (minder toegestaan), maar als iemand later Sentry aanzet en de origin vergeet toe te voegen, worden de foutmeldingen stil geblokkeerd: je monitoring lijkt dan te werken maar ontvangt niets. A) Lege lijsten zijn normaal — de policy wordt dan simpelweg strikter. Bij opstarten een informatieregel loggen welke origins actief zijn, zodat je in het log kunt zien wat is toegestaan B) Lege lijsten zijn normaal, en géén logging — het is een gewone toestand C) Bij opstarten een waarschuwing als er een Sentry-DSN of Umami-website-ID is geconfigureerd maar de bijbehorende origin niet in de CSP staat — vangt precies de fout waarbij monitoring stil niets ontvangt X) Anders (beschrijf hieronder na de [Answer]:-tag) [Answer]:C --- # Vervolgvragen (ronde 2) --- ## Follow-up Question 1 — Optie B bij vraag 1 kan technisch niet Je koos bij vraag 1 optie B: nonces of hashes voor styles. Ik moet dat terugleggen, want ik heb die optie te mild beschreven — hij is niet "theoretisch netter maar lastig", hij **werkt principieel niet** voor dit probleem. **Waarom niet:** een CSP-nonce werkt alleen op `