Om mijn website zoveel mogelijk te beschermen maak ik gebruik van diverse security headers in het .htaccess bestand.
Content Security Policy:
Een van de bekendere is de Content Security Policy header, afgekort CSP. Hiermee kan je aangeven welke interne en externe bestanden geladen mogen worden. Met interne bestanden worden de bestanden op jouw server bedoelt. Externe bestanden bevinden zich bijvoorbeeld bij Youtube, op een CDN (content delivery network) of bij Google Fonts.
Naast bestanden kan je met CSP ook aangeven of inline CSS of Javascript ingeladen mag worden. Op deze manier heb je volledige controle over wat ingeladen wordt.
WordPress & CSP:
Maak je gebruik van WordPress met een thema en een aantal plugins? Dan kom je er al snel achter dat het instellen van CSP een uitdaging kan zijn. Dit vereist veel testen van de voorkant (front-end) en de achterkant (wp-admin) van de website. Het toevoegen van domeinen aan de lijst kan weer nieuwe meldingen veroorzaken.
Eenmaal ingesteld is jouw website een stuk veiliger. Maar omdat plugins of thema’s updates krijgen kan het zo zijn dat je na 1 maand de CSP alweer bij moeten werken. Zo stapt plugin X over naar een Content Delivery Network of wisselt naar een andere.
Nieuwe en oude domeinen:
Ik test elke paar maanden mijn website met de browser web developer toolbar open. Als bestanden niet ingeladen kunnen worden verschijnt in de console tab een melding. Het toevoegen van een nieuw domein gemakkelijk. Alleen het verwijderen van een oud domein is een stuk lastiger omdat je niet altijd weet of deze nog gebruikt wordt.
Voorbeeld van een Content Security Policy:
Header set Content-Security-Policy "default-src www.timdehoog.nl; frame-ancestors www.timdehoog.nl *.wp.com; script-src 'unsafe-inline' 'unsafe-eval' 'self' *.wp.com; style-src 'unsafe-inline' www.timdehoog.nl; font-src data: www.timdehoog.nl; media-src www.timdehoog.nl; img-src data: www.timdehoog.nl *.w.org *.wp.com *.wordpress.com *.gravatar.com"
Hierboven zie je een simpel voorbeeld voor WordPress website.
- Gebruik je www.timdehoog.nl, dan worden alleen bestanden ingeladen via een URL die begint met https://www.timdehoog.nl
- Gebruik je timdehoog.nl, dan worden alleen bestanden ingeladen via een URL die begint met https://timdehoog.nl
- Gebruik je abcd.timdehoog.nl, dan worden alleen bestanden ingeladen via een URL die begint met https://abcd.timdehoog.nl
- Gebruik je *.timdehoog.nl, dan worden alleen bestanden ingeladen via een URL waarin het domein timdehoog.nl voorkomt
Het makkelijkste is natuurlijk *.timdehoog.nl, maar dit is ook het minst veilig. Het beste kan je volledige domeinnamen zoals www.timdehoog.nl of 1234.timdehoog.nl hanteren. Maar er zijn bedrijven, zoals Google, die met subdomeinen werken die kunnen wisselen.
Schrijf je de 10+ domeinen uit in jouw Content Security Policy waardoor deze heel lang wordt of gebruik je *.google.com waardoor je misschien wel 20+ subdomeinen toestaat?
In de afgelopen jaren heb ik voor deze situaties een afweging gemaakt tussen beveiliging of het overzichtelijk houden van mijn CSP. Daarom zie je in bovenstaand voorbeeld ook *.wp.com staan omdat er gebruik gemaakt worden van diverse wisselende subdomeinen. Hiermee voorkom ik dat mijn website opeens niet meer juist functioneert.
Header efficiënter schrijven voor productie en test omgeving
In bovenstaand voorbeeld zie je heel de tijd www.timdehoog.nl staan. Dit is de meest veilige instelling omdat alleen bestanden op www.timdehoog.nl worden ingeladen. Maar hier kleeft ook meteen een nadeel aan wanneer je gebruik maakt van een testomgeving zoals ontwikkeling.timdehoog.nl om nieuwe functionaliteiten te testen.
Dit betekent dat je telkens www.timdehoog.nl aan moet passen naar ontwikkeling.timdehoog.nl om ervoor te zorgen dat jouw website juist functioneert. Maar er zijn een aantal oplossingen.
Oplossing 1:
Maak gebruik van *.timdehoog.nl. Nadeel: niet de beste oplossing want alle subdomeinen worden dan geaccepteerd.
Oplossing 2:
Voeg beiden domeinnamen toe. Nadeel 1: de CSP wordt een stuk langer. Nadeel 2: stap je over van ontwikkeling.timdehoog.nl naar development.timdehoog.nl moet je de instellingen aanpassen.
Oplossing 3 < beste keuze:
Vervang www.timdehoog.nl door ‘self’. Hiermee wordt het domein bedoelt waarop de website bezocht wordt. Dus ‘self’ is identiek aan www.timdehoog.nl of ontwikkeling.timdehoog.nl wanneer de website op de ontwikkelomgeving wordt bezocht. Voordeel 1: minder onderhoud. Voordeel 2: kortere CSP 6 letters versus 16 en die winst maal het aantal keer dat het domein in de CSP voorkomt.
Meer verbeteringen mogelijk?
Je kan alleen nog meer verbeteringen doorvoeren door het aantal bronnen te beperken. Voor WordPress websites betekent dit al snel dat je minder plugins gaat gebruiken, maar die maken het juist zo makkelijk om functionaliteit toe te voegen.
Praktisch voorbeeld: bewaar de lettertypes op jouw webserver i.p.v. dat je ze download van Google Fonts.
De CSP van Timdehoog.nl in 2022:
Mijn CSP ziet er zo uit. Dat is geen geheim want deze is van iedere website openbaar. Je hebt zelfs websites waarmee je CSP kan testen zoals www.securityheaders.com.
Header set Content-Security-Policy "default-src 'self' *.wp.com csi.gstatic.com googleads.g.doubleclick.net www.google.com *.googlesyndication.com www.google-analytics.com www.googleapis.com pzz.to *.linkpizza.com pzz.events yoast.com; frame-ancestors 'self' *.wp.com; script-src 'unsafe-inline' 'unsafe-eval' 'self' *.googleapis.com *.googlesyndication.com *.googleadservices.com www.googletagmanager.com adservice.google.nl adservice.google.com cdn.ampproject.org *.googletagservices.com www.google-analytics.com *.wp.com pzz.io cdn.jsdelivr.net; style-src 'unsafe-inline' 'self' *.googleapis.com *.wp.com secure.gravatar.com *.bootstrapcdn.com cdn.jsdelivr.net; font-src data: 'self' fonts.gstatic.com *.wp.com wordpress.com *.bootstrapcdn.com; media-src 'self'; img-src data: 'self' *.w.org *.wp.com *.wordpress.com *.gravatar.com *.googlesyndication.com www.google-analytics.com ajax.googleapis.com"
Bovenstaande CSP houd o.a. rekening met:
- WordPress
- Google diensten zoals fonts / adsense
- Linkpizza
- Elementor ondersteuning
- Yoast ondersteuning
- Diverse Content Delivery Networks