CORS afhandelen in webapplicaties

0
188
Shutterstock/Gorodenkoff

CORS is een browsermechanisme waarmee servers de oorsprong van derden kunnen specificeren die bronnen van hen kunnen opvragen. Het is een beveiligingsbescherming die helpt voorkomen dat kwaadwillende sites gegevens stelen die eigendom zijn van andere bronnen.

CORS staat voor Cross-Origin Resource Sharing. Wanneer CORS wordt gebruikt om een ​​bron te laden, verzendt de browser meestal een “preflight” HTTP OPTIONS-verzoek. De server moet reageren met vermelding van de oorsprong waarmee hij zal communiceren. Het kan ook aanvullende beperkingen definiëren, zoals de HTTP-headers die kunnen worden verzonden.

De browser controleert de huidige oorsprong en het uitgaande verzoek aan de hand van de specificaties van de server. Het verzoek mag doorgaan als alle controles zijn geslaagd. Anders wordt het oorspronkelijke verzoek geannuleerd. Je ziet een waarschuwing in de console wanneer dit gebeurt.

Als CORS wordt gebruikt

Browsers dwingen CORS af voor Ajax- en Fetch-verzoeken. Het mechanisme zal ook worden gebruikt voor weblettertypen, WebGL-texturen en canvasafbeeldingen met drawImage(). Voor elk in aanmerking komend verzoek aan een derde partij moet een CORS-uitwisseling plaatsvinden.

CORS wordt niet afgedwongen als het verzoek wordt gezien als “eenvoudig”. Een eenvoudig verzoek moet GET, HEAD of POST zijn met een inhoudstype text/plain, application/x-www-form-urlencoded of multipart/form-data. De enige toegestane eenvoudige verzoekheaders zijn Accept, Accept-Language, Content-Language en Content-Type.

Als het verzoek niet aan alle bovenstaande criteria voldoet, wordt een CORS-uitwisseling gestart door moderne browsers. Het is belangrijk om te erkennen dat CORS een browsergebaseerde technologie is – u zult CORS nooit tegenkomen wanneer u handmatig verzoeken doet, zoals met curl in uw terminal.

CORS-uitwisselingen sturen niet altijd een OPTIONS-preflightverzoek. Een preflight wordt gebruikt wanneer het verzoek “bijwerkingen” op de server. Dit is over het algemeen het geval voor andere aanvraagmethoden dan GET.

Stel je een POST-verzoek voor aan /api/users/create. De server zou altijd een nieuwe gebruiker maken, maar de browser kan toegang tot het antwoord weigeren als het verzoek onderworpen was aan CORS. Door eerst een OPTIONS-verzoek te verzenden, heeft de server de kans om het echte verzoek expliciet af te wijzen. Dit zorgt ervoor dat het gebruikersaccount niet echt wordt aangemaakt.

Cors Client-Side afhandelen

Hoewel CORS een browsertechnologie is, kunt u deze niet rechtstreeks beïnvloeden met code aan de clientzijde. Dit voorkomt dat kwaadaardige scripts CORS-beveiligingen omzeilen om gegevens van domeinen van derden te laden.

CORS is meestal transparant, dus u zult niet doorhebben dat het in werking is. Als een CORS-uitwisseling mislukt, ziet uw JavaScript-code een algemene netwerkfout. Het is niet mogelijk om precieze details te krijgen over wat er mis is gegaan, omdat dit een veiligheidsrisico zou zijn. De volledige details worden vastgelegd in de console.

De enige manier om een ​​CORS-fout op te lossen, is ervoor te zorgen dat uw server de juiste responsheaders verzendt. Laten we nu eens kijken hoe dat wordt gedaan.

Cors Server-Side afhandelen

U moet er eerst voor zorgen dat uw server OPTIONS-verzoeken correct afhandelt. Mogelijk moet u een nieuwe route maken in uw webframework. Over het algemeen moet u OPTIONS-verzoeken accepteren voor elk eindpunt dat mogelijk een cross-origin-verzoek van een browser ontvangt. Het antwoord hoeft geen hoofdtekst te hebben, maar moet specifieke headers bevatten die de browser informeren hoe verder te gaan.

Begin met het toevoegen van de Access-Control-Allow-Origin-header. Dit specificeert de oorsprong van de derde partij die mag communiceren met uw eindpunt. Er kan slechts één oorsprong worden opgegeven; u kunt meerdere oorsprongen afhandelen door de waarde van de kop dynamisch in te stellen op de oorsprong van waaruit het verzoek is verzonden. U kunt de huidige oorsprong uit de kop van de oorsprongsaanvraag halen.

Access-Control-Allow-Origin accepteert * als een speciale wildcard-waarde. Dit maakt CORS-verzoeken van alle herkomst mogelijk. Wees voorzichtig bij het gebruik van deze – specifiek zijn met de toegestane oorsprong geeft u meer controle en voorkomt dat kwaadaardige scripts gegevens van uw server opvragen.

Access-Control-Allow-Origin moet worden opgenomen in het antwoord van uw server op het echte verzoek, evenals het OPTIONS-antwoord. Zodra deze enkele header is ingesteld, is een basisuitwisseling met een externe browserclient toegestaan.

Cross-Origin-headers specificeren

CORS-verzoeken ondersteunen meestal alleen de “eenvoudige” hierboven vermelde verzoekheaders. Als u een andere header moet gebruiken, zoals Autorisatie of een aangepaste header, moet uw server dit expliciet toestaan ​​in het preflight-antwoord.

Stel de Access-Control-Allow-Headers-header in. De waarde moet een door komma's gescheiden lijst met kopnamen zijn die worden geaccepteerd met het echte verzoek.

Access-Control-Allow-Headers: Autorisatie, X-Custom-Header

De browser zou nu een verzoek toestaan ​​met ofwel de Authorization of X-Custom-Header headers om door te gaan.

Wanneer de browser verzendt een CORS-preflightverzoek, zal het de Access-Control-Request-Headers-header verzenden. Dit bevat de lijst met headers die met het daadwerkelijke verzoek worden verzonden. Uw servercode kan deze informatie gebruiken om te bepalen hoe op het preflight-verzoek moet worden gereageerd.

Beperken tot specifieke aanvraagmethoden

Net als bij het specificeren van aanvraagheaders, kunnen servereindpunten bepalen welke HTTP-methoden cross-origin moeten worden toegestaan. Stel de Access-Control-Allow-Methods-header in als een door komma's gescheiden lijst met methodenamen.

Access-Control-Allow-Methods: GET, POST, DELETE

De browser verzendt het Access-Control-Request- Methode-header met CORS-preflights. Dit laat uw server weten welke HTTP-methode zal worden gebruikt om het laatste verzoek te doen.

Cookies en referenties

CORS-verzoeken verzenden normaal gesproken geen cookies omdat ze gevoelige referenties kunnen bevatten die de afzender identificeren. Als u cookies moet opnemen met een cross-origin-verzoek, moet u dit expliciet inschakelen in uw client-side code:

fetch(“https://localhost/demo”, { mode: “cors”, referenties: “opnemen” });

Bovendien moet de server de Access-Control-Allow-Credentials: true response-header instellen om aan te geven dat hij ermee instemt dat cookies met referenties kunnen worden uitgewisseld.

Als u Access-Control-Allow-Credentials gebruikt, kan niet het jokerteken (*) gebruiken met Access-Control-Allow-Origin. De server moet in plaats daarvan een expliciete oorsprong specificeren om de privacy van de gebruiker te waarborgen. Als het jokerteken wordt verzonden, mislukt de browser het verzoek met een CORS-fout.

Preflight-caching

CORS OPTIONS-preflights voegen een overhead toe aan elk verzoek dat u doet. Hoewel de vertraging nauwelijks waarneembaar zou moeten zijn op een goede netwerkverbinding, is het niettemin verspillend wanneer u hetzelfde eindpunt meerdere keren snel achter elkaar belt.

U kunt de browser vertellen om te cachen preflight-reacties door de header Access-Control-Max-Age in te stellen. De waarde moet de tijd in seconden zijn waarin de browser het antwoord mag cachen. Daaropvolgende verzoeken aan hetzelfde eindpunt binnen de gegeven periode zullen geen CORS-preflight verzenden.

Conclusie

CORS kan verwarrend lijken de eerste keer dat u het tegenkomt. Het is een browsertechnologie die wordt bestuurd door serverreacties. CORS is onvermijdelijk en toch ook oncontroleerbaar, tenzij je toegang hebt tot de server-side code waarmee je communiceert.

De daadwerkelijke implementatie van CORS is vrij eenvoudig. Zorg ervoor dat uw API of CDN de juiste responsheaders verzendt, met name Access-Control-Allow-Origin. Je hebt dan veilige communicatie tussen verschillende oorsprongen die je helpt beschermen tegen slechte actoren.