Wanneer je op het internet aan het surfen bent en je een website bezoekt, kan het zijn dat je wel eens een melding krijgt dat de bron van een bepaalde inhoud geblokkeerd is vanwege CORS. Misschien vraag je je af wat CORS eigenlijk is en waarom het van belang is voor je surfervaring. Nou, je bent hier aan het juiste adres. CORS, oftewel Cross-Origin Resource Sharing, is een mechanisme dat browsers gebruiken om te bepalen of het veilig is om gegevens te delen tussen verschillende websites. We gaan dieper in op wat CORS precies is en waarom het van cruciaal belang is voor het functioneren van moderne webtoepassingen.
Wat is een cross-origin resource sharing (CORS)?
Cross-Origin Resource Sharing (CORS) is een mechanisme dat toegangscontrole mogelijk maakt op webbronnen van een ander domein. In eenvoudige bewoordingen stelt CORS websites in staat om middelen te delen met andere websites die zich in een ander domein bevinden. Dit is van cruciaal belang voor moderne webtoepassingen die vaak externe bronnen, zoals API’s, nodig hebben om goed te kunnen functioneren.
Waarom hebben we CORS nodig?
CORS is nodig vanwege een security-maatregel genaamd het same-origin policy. Deze policy beperkt de mogelijkheid van webpagina’s om bronnen op te halen van een ander domein dan waaruit ze zijn geladen. Dit is om te voorkomen dat kwaadwillende websites toegang krijgen tot gevoelige informatie van een andere website die je als gebruiker hebt geopend. Hoewel dit een effectieve beveiligingsmaatregel is, kan het ook problemen opleveren voor legitieme use-cases, zoals het ophalen van gegevens van een externe API. CORS biedt een oplossing voor dit probleem door het mogelijk te maken dat websites toestemming kunnen vragen om bronnen van een ander domein te delen.
Hoe werkt CORS in de basis?
Om CORS te begrijpen, moet je weten dat er twee soorten HTTP-verzoeken zijn: same-origin verzoeken en cross-origin verzoeken. Same-origin verzoeken zijn verzoeken die worden gedaan vanuit een webpagina naar hetzelfde domein waaruit de webpagina is geladen. Deze verzoeken worden zonder beperkingen uitgevoerd en geen speciale headers zijn nodig.
Cross-origin verzoeken daarentegen zijn verzoeken die worden gedaan naar een ander domein. Deze verzoeken zijn niet standaard toegestaan vanwege de same-origin policy. Om cross-origin verzoeken mogelijk te maken, moet de server van het andere domein CORS-headers terugsturen als reactie op het verzoek. Deze headers geven toestemming aan de webbrowser om de bron te delen met het domein waaruit het verzoek is gedaan.
De belangrijkste CORS-header is ‘Access-Control-Allow-Origin’, die aangeeft welke domeinen toegang hebben tot de bron. Als een resource bijvoorbeeld toegankelijk moet zijn voor alle domeinen, kan de server de header ‘Access-Control-Allow-Origin: *’ retourneren. Als een resource alleen toegankelijk moet zijn voor een specifiek domein, kan de header ‘Access-Control-Allow-Origin: https://jouwdomein.nl’ worden gebruikt.
Verschil tussen same-origin en cross-origin verzoeken
Het belangrijkste verschil tussen same-origin en cross-origin verzoeken is de aanwezigheid van de CORS-headers en de toegang die deze headers bieden. Bij same-origin verzoeken worden de bronnen zonder beperkingen gedeeld, terwijl bij cross-origin verzoeken de server expliciete toestemming moet geven om de bronnen te delen. Dit betekent dat een webpagina cross-origin bronnen kan ophalen, mits de server toestemming geeft.
Zonder CORS zou de same-origin policy voorkomen dat websites externe resources kunnen gebruiken. Met CORS zijn websites in staat om veilig te communiceren en gegevens uit te wisselen met andere websites, waardoor de gebruikerservaring wordt verbeterd en het potentieel voor ontwikkeling wordt vergroot.
Hoe stel je een CORS-beleid in?
Als je een webapplicatie ontwikkelt die gebruik maakt van API’s op verschillende domeinen, kan het zijn dat je te maken krijgt met het cross-origin resource sharing (CORS) probleem. CORS is een beveiligingsmechanisme dat bepaalt welke bronnen op een ander domein toegankelijk zijn voor een webpagina. Om CORS correct in te stellen voor jouw applicatie, moet je een aantal belangrijke stappen volgen.
CORS-headers begrijpen
Voordat je kunt beginnen met het instellen van een CORS-beleid, is het belangrijk om de verschillende CORS-headers te begrijpen. CORS-headers zijn aanvullende HTTP-headers die informatie bevatten over de toegangsregels voor een bepaalde bron. De belangrijkste CORS-headers zijn:
- Access-Control-Allow-Origin: geeft aan welke domeinen toegang hebben tot de bron. Bijvoorbeeld: Access-Control-Allow-Origin: example.com.
- Access-Control-Allow-Methods: specificeert welke HTTP-methoden zijn toegestaan bij het benaderen van de bron. Bijvoorbeeld: Access-Control-Allow-Methods: GET, POST.
- Access-Control-Allow-Headers: definieert welke HTTP-headers zijn toegestaan bij het benaderen van de bron. Bijvoorbeeld: Access-Control-Allow-Headers: Content-Type, Authorization.
- Access-Control-Allow-Credentials: geeft aan of de browser verificatiegegevens (zoals cookies) mag meesturen bij het benaderen van de bron. Bijvoorbeeld: Access-Control-Allow-Credentials: true.
- Access-Control-Max-Age: specificeert hoelang de preflight request (zie volgende sectie) geldig blijft zonder opnieuw te worden uitgevoerd. Bijvoorbeeld: Access-Control-Max-Age: 3600 (in seconden).
Door het begrijpen van deze CORS-headers kun je het CORS-beleid van jouw webapplicatie beter configureren.
De rol van de preflight request
Wanneer een webpagina een cross-origin verzoek doet dat bepaalde kenmerken heeft, zoals het gebruik van specifieke HTTP-methoden (zoals PUT of DELETE) of aangepaste headers, zal de browser eerst een preflight request uitvoeren voordat het daadwerkelijke verzoek wordt verzonden. Een preflight request is een OPTIONS-verzoek dat wordt gebruikt om te controleren of de server het verzoek accepteert en welke CORS-headers worden ondersteund.
Tijdens de preflight request worden de Access-Control-headers uitgewisseld om te bepalen of de server het verzoek mag ontvangen. Als de server de preflight request goedkeurt, zal de browser het daadwerkelijke verzoek verzenden met de juiste CORS-headers. Als de server de preflight request afwijst, zal de browser een foutmelding tonen en het verzoek niet verzenden.
Specifieke instellingen voor verschillende serveromgevingen
Om een CORS-beleid correct in te stellen voor verschillende serveromgevingen, moet je rekening houden met de servertechnologie die je gebruikt. Dit zijn enkele voorbeelden:
Apache
Voor Apache-servers kun je een .htaccess-bestand maken en de volgende regels toevoegen:
- Header set Access-Control-Allow-Origin “*”
- Header set Access-Control-Allow-Methods “GET, POST, PUT, DELETE, OPTIONS”
Nginx
Voor Nginx-servers kun je de volgende configuratie toevoegen aan je serverblok:
- add_header ‘Access-Control-Allow-Origin’ ‘*’;
- add_header ‘Access-Control-Allow-Methods’ ‘GET, POST, PUT, DELETE, OPTIONS’;
Node.js met Express.js
Voor een Node.js server met Express.js kun je de volgende middleware toevoegen aan je applicatie:
- const express = require(‘express’);
const app = express();
const cors = require(‘cors’); - app.use(cors());
Deze configuraties zijn slechts voorbeelden en kunnen worden aangepast aan jouw specifieke behoeften. Raadpleeg de documentatie van je servertechnologie voor gedetailleerde instructies.
Programmeren met CORS
Als je wilt programmeren met Cross-Origin Resource Sharing (CORS), zijn er een paar belangrijke zaken waar je op moet letten. In dit deel gaan we Cors in actie zien met JavaScript en bespreken we veelvoorkomende problemen en oplossingen bij CORS.
Cors in actie zien met JavaScript
Om CORS in actie te zien met JavaScript, laten we een voorbeeld bekijken van hoe je een cross-origin verzoek kunt maken en de reactie kunt verwerken.
- Stap 1: Zorg ervoor dat je JavaScript code wordt uitgevoerd vanuit een webpagina die is gehost op een andere origin dan de server waarvan je bronnen wilt laden. Dit is een typisch scenario waarbij CORS van toepassing is.
- Stap 2: Maak een XMLHttpRequest-object aan om een verzoek te maken naar een andere server. Bijvoorbeeld:
“`javascript
var xhr = new XMLHttpRequest();
xhr.open(‘GET’, ‘https://api.example.com/data’, true);
xhr.onload = function() {
if (xhr.status === 200) {
// Succesvolle respons verwerken
console.log(xhr.responseText);
}
};
xhr.send();
“`
In dit voorbeeld maken we een GET-verzoek naar ‘https://api.example.com/data’. Als het verzoek succesvol is, loggen we de reactie in de console.
Veelvoorkomende problemen en oplossingen bij CORS
Hoewel CORS bedoeld is om veilige cross-origin verzoeken mogelijk te maken, kunnen er soms problemen optreden. Dit zijn enkele veelvoorkomende problemen en mogelijke oplossingen:
1. Probleem: CORS verzoek wordt geblokkeerd door de server
Als de server het verzoek blokkeert vanwege een onjuist ingesteld CORS-beleid, kun je een aantal oplossingen proberen:
- Zorg ervoor dat het verzoek wordt gemaakt vanuit een toegestane oorsprong (origin). Het kan zijn dat de server alleen verzoeken accepteert van specifieke origins.
- Controleer de CORS-headers in de verzoek- en reactieheaders. Mogelijk ontbreekt er een vereiste header of zijn de headers onjuist geconfigureerd.
- Als je toegang hebt tot de serverconfiguratie, controleer dan het CORS-beleid en pas dit aan indien nodig.
2. Probleem: Credentials worden niet doorgegeven tijdens het verzoek
Als je credentials, zoals cookies of authenticatietokens, wilt doorgeven tijdens het CORS-verzoek, moet je enkele extra stappen nemen:
- Zorg ervoor dat de ‘withCredentials’-eigenschap van het XMLHttpRequest-object is ingesteld op ’true’. Dit zorgt ervoor dat credentials worden meegestuurd met het verzoek.
- Controleer ook of de server het accepteren van credentials toestaat door de ‘Access-Control-Allow-Credentials’ header in de reactie te controleren.
3. Probleem: Preflight request wordt gemaakt voor elk verzoek
De preflight request is een extra verzoek dat door de browser wordt gemaakt voordat het werkelijke verzoek wordt gemaakt. Dit kan vertragend werken en voor problemen zorgen. Om dit probleem te minimaliseren, kun je de volgende stappen ondernemen:
- Zorg ervoor dat de server de juiste CORS-headers retourneert in de preflight response. Dit zorgt ervoor dat de browser het werkelijke verzoek toestaat zonder een preflight request.
- Als het mogelijk is, maak dan gebruik van eenvoudige verzoeken zoals GET of POST zonder speciale headers. Deze verzoeken vereisen geen preflight request.
Dit waren slechts enkele veelvoorkomende problemen en oplossingen bij CORS. Het belangrijkste is om goed te begrijpen hoe CORS werkt en hoe je de juiste headers en configuraties kunt gebruiken om probleemloze cross-origin verzoeken mogelijk te maken.
Beveiliging en CORS
Een goed geconfigureerd CORS-beleid is essentieel voor de beveiliging van je website of app. Het naleven van best practices helpt bij het beschermen van gebruikersgegevens, voorkomt aanvallen en minimaliseert de kans op datalekken. Aan de andere kant kan een verkeerd geconfigureerd CORS-beleid ernstige risico’s met zich meebrengen en de veiligheid van je applicatie in gevaar brengen.
Risico’s van een verkeerd geconfigureerd CORS-beleid
Als je CORS-beleid verkeerd is geconfigureerd, kunnen kwaadwillende actoren misbruik maken van je servers en gevoelige informatie stelen. Dit zijn enkele risico’s die je kunt tegenkomen:
- Verkeerd toegestane bronnen: Een belangrijk risico is dat je per ongeluk bronnen van een andere oorsprong toestaat dan zou moeten. Dit kan leiden tot het lekken van gevoelige informatie naar ongeautoriseerde partijen.
- Verkeerde blokkering: Aan de andere kant kan het verkeerd blokkeren van verzoeken van andere oorsprong resulteren in een slechte gebruikerservaring en functionaliteit van je applicatie beperken. Het is belangrijk om de juiste balans te vinden tussen beveiliging en functionaliteit.
- CSRF-aanvallen: Een verkeerd geconfigureerd CORS-beleid kan het risico op Cross-Site Request Forgery (CSRF) aanvallen vergroten. Dit type aanval kan ertoe leiden dat een gebruiker ongewenste acties uitvoert zonder dat hij/zij zich er bewust van is. Een juiste CORS-configuratie kan helpen om dit risico te verminderen.
Best practices voor CORS-configuraties
Om de risico’s van een verkeerd geconfigureerd CORS-beleid te minimaliseren, zijn er enkele best practices die je kunt volgen:
Wees specifiek in toegestane bronnen
Sta alleen bronnen van specifieke oorsprong toe die noodzakelijk zijn voor de werking van je applicatie. Dit vermindert het risico van onbedoelde toegang en voorkomt dat ongeautoriseerde partijen toegang krijgen tot gevoelige gegevens.
Gebruik de juiste methoden en headers
Zorg ervoor dat je alleen de juiste HTTP-methoden en headers toestaat voor cross-origin verzoeken. Bijvoorbeeld, als je geen PUT- of DELETE-verzoeken verwacht, blokkeer deze dan expliciet om ongewenste acties te voorkomen.
Implementeer CSRF-bescherming
Om het risico op CSRF-aanvallen te verminderen, implementeer CSRF-beschermingstechnieken. Dit kan worden gedaan door het genereren en controleren van unieke tokens voor elke verzoek.
Houd je CORS-beleid up-to-date
Zorg ervoor dat je regelmatig je CORS-beleid controleert en bijwerkt om aan te passen aan nieuwe beveiligingsstandaarden en ontwikkelingen. Dit helpt bij het verminderen van het risico op kwetsbaarheden door verouderde configuraties.
Door deze beste praktijken te volgen, kun je de veiligheid van je applicatie versterken en de kans op beveiligingslekken aanzienlijk verminderen.