En omfattande guide för att förbÀttra frontend-sÀkerheten med Content Security Policy (CSP) och Cross-Origin Resource Sharing (CORS). Skydda dina webbapplikationer frÄn moderna hot.
HÀrdning av frontend-sÀkerhet: Content Security Policy och CORS
I dagens sammanlÀnkade digitala landskap Àr frontend-sÀkerhet av största vikt. Webbapplikationer Àr alltmer mÄltavlor för sofistikerade attacker, vilket gör robusta sÀkerhetsÄtgÀrder avgörande. TvÄ viktiga komponenter i en sÀker frontend-arkitektur Àr Content Security Policy (CSP) och Cross-Origin Resource Sharing (CORS). Den hÀr omfattande guiden ger en djupgÄende titt pÄ dessa tekniker och erbjuder praktiska exempel och anvÀndbara insikter för att hjÀlpa dig att stÀrka dina webbapplikationer mot moderna hot.
Vad Àr Content Security Policy (CSP)?
Content Security Policy (CSP) Àr ett extra sÀkerhetslager som hjÀlper till att upptÀcka och mildra vissa typer av attacker, inklusive Cross-Site Scripting (XSS) och datainjektionsattacker. CSP implementeras genom att webbservern skickar en Content-Security-Policy HTTP-responshuvud till webblÀsaren. Denna rubrik definierar en vitlista över kÀllor som webblÀsaren fÄr lÀsa in resurser frÄn. Genom att begrÀnsa kÀllorna till innehÄll som en webblÀsare kan lÀsa in gör CSP det betydligt svÄrare för angripare att injicera skadlig kod pÄ din webbplats.
Hur CSP fungerar
CSP fungerar genom att instruera webblÀsaren att endast lÀsa in resurser (t.ex. skript, formatmallar, bilder, teckensnitt) frÄn godkÀnda kÀllor. Dessa kÀllor specificeras i CSP-huvudet med hjÀlp av direktiv. Om en webblÀsare försöker lÀsa in en resurs frÄn en kÀlla som inte Àr uttryckligen tillÄten, kommer den att blockera begÀran och rapportera en övertrÀdelse.
CSP-direktiv: En omfattande översikt
CSP-direktiv styr de typer av resurser som kan lÀsas in frÄn specifika kÀllor. HÀr Àr en genomgÄng av nÄgra av de viktigaste direktiven:
- default-src: Anger standardkÀlla för alla innehÄllstyper. Detta Àr ett reservdirektiv som gÀller nÀr andra, mer specifika direktiv inte finns.
- script-src: Anger de kÀllor frÄn vilka skript kan lÀsas in. Detta Àr avgörande för att förhindra XSS-attacker.
- style-src: Anger de kÀllor frÄn vilka formatmallar kan lÀsas in.
- img-src: Anger de kÀllor frÄn vilka bilder kan lÀsas in.
- font-src: Anger de kÀllor frÄn vilka teckensnitt kan lÀsas in.
- media-src: Anger de kÀllor frÄn vilka ljud och video kan lÀsas in.
- object-src: Anger de kÀllor frÄn vilka plugins (t.ex. Flash) kan lÀsas in. Detta stÀlls ofta in pÄ 'none' för att inaktivera plugins helt pÄ grund av deras inneboende sÀkerhetsrisker.
- frame-src: Anger de kÀllor frÄn vilka ramar (t.ex. <iframe>) kan lÀsas in.
- connect-src: Anger de webbadresser som anvÀndaragenten kan ansluta till med hjÀlp av skriptgrÀnssnitt som XMLHttpRequest, WebSocket och EventSource.
- base-uri: Anger de webbadresser som kan anvÀndas i ett dokuments <base>-element.
- form-action: Anger de webbadresser till vilka formulÀrinlÀmningar kan skickas.
- upgrade-insecure-requests: Instruerar anvÀndaragenten att automatiskt uppgradera osÀkra begÀranden (HTTP) till sÀkra begÀranden (HTTPS).
- report-uri: Anger en webbadress dÀr webblÀsaren ska skicka rapporter om CSP-övertrÀdelser. Detta direktiv Àr förÄldrat till förmÄn för `report-to`.
- report-to: Anger ett rapporteringsgruppnamn som definieras i `Report-To`-huvudet, dÀr webblÀsaren ska skicka rapporter om CSP-övertrÀdelser.
CSP-kÀlllistnyckelord
Inom CSP-direktiv kan du anvÀnda kÀlllistnyckelord för att definiera tillÄtna kÀllor. HÀr Àr nÄgra vanliga nyckelord:
- 'self': TillÄter resurser frÄn samma ursprung (schema och vÀrd) som dokumentet.
- 'none': Förbjuder resurser frÄn alla kÀllor.
- 'unsafe-inline': TillÄter anvÀndning av inline-skript och stilar (t.ex. <script>-taggar och stilattribut). AnvÀnd med extrem försiktighet eftersom det avsevÀrt försvagar CSP-skyddet mot XSS.
- 'unsafe-eval': TillÄter anvÀndning av dynamiska kodutvÀrderingsfunktioner som
eval()ochFunction(). AnvÀnd med extrem försiktighet eftersom det introducerar betydande sÀkerhetsrisker. - 'unsafe-hashes': TillÄter specifika inline-hÀndelsehanterare eller <style>-taggar som matchar en specificerad hash. KrÀver webblÀsarstöd. AnvÀnd med försiktighet.
- 'strict-dynamic': Specificerar att förtroendet som uttryckligen ges till ett skript som finns i markeringen, genom att Ätfölja det med en nonce eller hash, ska spridas till alla skript som laddas av det rotskriptet.
- data: TillÄter data: URI:er (t.ex. inline-bilder kodade som base64). AnvÀnd med försiktighet.
- https:: TillÄter att resurser lÀses in över HTTPS frÄn vilken domÀn som helst.
- [vÀrdnamn]: TillÄter resurser frÄn en specifik domÀn (t.ex. example.com). Du kan ocksÄ ange ett portnummer (t.ex. example.com:8080).
- [schema]://[vÀrdnamn]:[port]: En fullstÀndigt kvalificerad URI, som tillÄter resurser frÄn det specificerade schemat, vÀrden och porten.
Praktiska CSP-exempel
LÄt oss titta pÄ nÄgra praktiska exempel pÄ CSP-huvuden:
Exempel 1: GrundlÀggande CSP med 'self'
Denna policy tillÄter resurser endast frÄn samma ursprung:
Content-Security-Policy: default-src 'self'
Exempel 2: TillÄta skript frÄn en specifik domÀn
Denna policy tillÄter skript frÄn din egen domÀn och en betrodd CDN:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com
Exempel 3: Inaktivera inline-skript och stilar
Denna policy förbjuder inline-skript och stilar, vilket Àr ett starkt försvar mot XSS:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'
Viktigt: Att inaktivera inline-skript krÀver att du refaktorerar din HTML för att flytta inline-skript till externa filer.
Exempel 4: AnvÀnda Nonces för Inline-skript
Om du mÄste anvÀnda inline-skript, anvÀnd nonces (kryptografiskt slumpmÀssiga engÄngstoken) för att vitlista specifika inline-skriptblock. Detta Àr sÀkrare Àn 'unsafe-inline'. Servern mÄste generera en unik nonce för varje begÀran och inkludera den i bÄde CSP-huvudet och <script>-taggen.
Content-Security-Policy: default-src 'self'; script-src 'nonce-r4nd0mN0nc3'; style-src 'self'
<script nonce="r4nd0mN0nc3"> console.log('Inline script'); </script>
Obs: Kom ihÄg att generera en ny nonce för varje begÀran. à teranvÀnd inte nonces!
Exempel 5: AnvÀnda Hashar för Inline-stilar
I likhet med nonces kan hashvÀrden anvÀndas för att vitlista specifika inline-<style>-block. Detta görs genom att generera en SHA256-, SHA384- eller SHA512-hash av stilinnehÄllet.
Content-Security-Policy: default-src 'self'; style-src 'sha256-HASHEDSTYLES'
<style sha256="HASHEDSTYLES"> body { background-color: #f0f0f0; } </style>
Obs: Hashar Àr mindre flexibla Àn nonces eftersom alla Àndringar av stilinnehÄllet kommer att ogiltigförklara hashen.
Exempel 6: Rapportera CSP-övertrÀdelser
För att övervaka CSP-övertrÀdelser, anvÀnd direktivet report-uri eller report-to:
Content-Security-Policy: default-src 'self'; report-to csp-endpoint;
Du mÄste ocksÄ konfigurera Report-To-huvudet. Huvudet Report-To definierar en eller flera rapporteringsgrupper, som anger var och hur rapporter ska skickas.
Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"https://example.com/csp-report"}]}
Testa och distribuera CSP
Implementering av CSP krÀver noggrann planering och testning. Börja med en restriktiv policy och lossa den gradvis efter behov. AnvÀnd huvudet Content-Security-Policy-Report-Only för att testa din policy utan att blockera resurser. Detta huvud rapporterar övertrÀdelser utan att tillÀmpa policyn, vilket gör att du kan identifiera och ÄtgÀrda problem innan du distribuerar policyn i produktion.
Content-Security-Policy-Report-Only: default-src 'self'; report-to csp-endpoint;
Analysera rapporterna som genereras av webblÀsaren för att identifiera eventuella övertrÀdelser och justera din policy dÀrefter. NÀr du Àr sÀker pÄ att din policy fungerar korrekt distribuerar du den med huvudet Content-Security-Policy.
BÀsta metoder för CSP
- Börja med en default-src: Definiera alltid en
default-srcför att faststÀlla en grundlÀggande policy. - Var specifik: AnvÀnd specifika direktiv och kÀlllistnyckelord för att begrÀnsa omfattningen av din policy.
- Undvik 'unsafe-inline' och 'unsafe-eval': Dessa nyckelord försvagar CSP avsevÀrt och bör undvikas nÀr det Àr möjligt.
- AnvÀnd nonces eller hashvÀrden för inline-skript och stilar: Om du mÄste anvÀnda inline-skript eller stilar, anvÀnd nonces eller hashvÀrden för att vitlista specifika kodblock.
- Ăvervaka CSP-övertrĂ€delser: AnvĂ€nd direktivet
report-uriellerreport-toför att övervaka CSP-övertrÀdelser och justera din policy dÀrefter. - Testa noggrant: AnvÀnd huvudet
Content-Security-Policy-Report-Onlyför att testa din policy innan du distribuerar den i produktion. - Iterera och förfina: CSP Ă€r inte en engĂ„ngskonfiguration. Ăvervaka och förfina kontinuerligt din policy för att anpassa dig till förĂ€ndringar i din applikation och hotlandskapet.
Vad Àr Cross-Origin Resource Sharing (CORS)?
Cross-Origin Resource Sharing (CORS) Àr en mekanism som tillÄter webbsidor frÄn ett ursprung (domÀn) att komma Ät resurser frÄn ett annat ursprung. Som standard tillÀmpar webblÀsare en Same-Origin Policy, som hindrar skript frÄn att göra förfrÄgningar till ett annat ursprung Àn det som skriptet kommer ifrÄn. CORS ger ett sÀtt att selektivt lÀtta pÄ denna begrÀnsning, vilket möjliggör legitima korsursprungsförfrÄgningar samtidigt som det skyddar mot skadliga attacker.
FörstÄ Same-Origin Policy
Same-Origin Policy Àr en grundlÀggande sÀkerhetsmekanism som förhindrar ett skadligt skript frÄn en webbplats frÄn att komma Ät kÀnslig data pÄ en annan webbplats. Ett ursprung definieras av schemat (protokoll), vÀrden (domÀn) och porten. TvÄ webbadresser har samma ursprung om och endast om de har samma schema, vÀrd och port.
Till exempel:
https://www.example.com/app1/index.htmlochhttps://www.example.com/app2/index.htmlhar samma ursprung.https://www.example.com/index.htmlochhttp://www.example.com/index.htmlhar olika ursprung (olika schema).https://www.example.com/index.htmlochhttps://sub.example.com/index.htmlhar olika ursprung (olika vÀrd).https://www.example.com:8080/index.htmlochhttps://www.example.com:80/index.htmlhar olika ursprung (olika port).
Hur CORS fungerar
NÀr en webbsida gör en korsursprungsbegÀran skickar webblÀsaren först en "förhandsbegÀran" till servern. FörhandsbegÀran anvÀnder HTTP OPTIONS-metoden och innehÄller huvuden som indikerar HTTP-metoden och huvuden som den faktiska begÀran kommer att anvÀnda. Servern svarar sedan med huvuden som indikerar om korsursprungsbegÀran Àr tillÄten.
Om servern tillÄter begÀran inkluderar den huvudet Access-Control-Allow-Origin i svaret. Detta huvud specificerar de ursprung som fÄr komma Ät resursen. WebblÀsaren fortsÀtter sedan med den faktiska begÀran. Om servern inte tillÄter begÀran inkluderar den inte huvudet Access-Control-Allow-Origin, och webblÀsaren blockerar begÀran.
CORS-huvuden: En detaljerad titt
CORS förlitar sig pÄ HTTP-huvuden för att kommunicera mellan webblÀsaren och servern. HÀr Àr de viktigaste CORS-huvuden:
- Access-Control-Allow-Origin: Anger de ursprung som fÄr komma Ät resursen. Detta huvud kan innehÄlla ett specifikt ursprung (t.ex.
https://www.example.com), en jokertecken (*) ellernull. Att anvÀnda*tillÄter begÀranden frÄn vilket ursprung som helst, vilket generellt sett inte rekommenderas av sÀkerhetsskÀl. Att anvÀnda `null` Àr endast lÀmpligt för "opak svar" som nÀr resursen hÀmtas med protokollet `file://` eller en data-URI. - Access-Control-Allow-Methods: Anger de HTTP-metoder som Àr tillÄtna för korsursprungsbegÀran (t.ex.
GET, POST, PUT, DELETE). - Access-Control-Allow-Headers: Anger de HTTP-huvuden som Àr tillÄtna i korsursprungsbegÀran. Detta Àr viktigt för att hantera anpassade huvuden.
- Access-Control-Allow-Credentials: Indikerar om webblÀsaren ska inkludera autentiseringsuppgifter (t.ex. cookies, auktoriseringshuvuden) i korsursprungsbegÀran. Detta huvud mÄste stÀllas in pÄ
trueför att tillÄta autentiseringsuppgifter. - Access-Control-Expose-Headers: Anger vilka huvuden som kan exponeras för klienten. Som standard exponeras endast en begrÀnsad uppsÀttning huvuden.
- Access-Control-Max-Age: Anger den maximala tid (i sekunder) som webblÀsaren kan cachelagra förhandsbegÀran.
- Origin: Detta Àr en begÀranshuvud som skickas av webblÀsaren för att indikera begÀranens ursprung.
- Vary: Ett allmÀnt HTTP-huvud, men viktigt för CORS. NÀr `Access-Control-Allow-Origin` genereras dynamiskt bör huvudet `Vary: Origin` inkluderas i svaret för att instruera cachningsmekanismer att svaret varierar beroende pÄ begÀranshuvudet `Origin`.
Praktiska CORS-exempel
LÄt oss titta pÄ nÄgra praktiska exempel pÄ CORS-konfigurationer:
Exempel 1: TillÄta begÀranden frÄn ett specifikt ursprung
Denna konfiguration tillÄter endast begÀranden frÄn https://www.example.com:
Access-Control-Allow-Origin: https://www.example.com
Exempel 2: TillÄta begÀranden frÄn valfritt ursprung (rekommenderas inte)
Denna konfiguration tillÄter begÀranden frÄn valfritt ursprung. AnvÀnd med försiktighet eftersom det kan introducera sÀkerhetsrisker:
Access-Control-Allow-Origin: *
Exempel 3: TillÄta specifika metoder och huvuden
Denna konfiguration tillÄter metoderna GET, POST och PUT, och huvudena Content-Type och Authorization:
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Exempel 4: TillÄta autentiseringsuppgifter
För att tillÄta autentiseringsuppgifter (t.ex. cookies) mÄste du stÀlla in Access-Control-Allow-Credentials pÄ true och ange ett specifikt ursprung (du kan inte anvÀnda * nÀr du tillÄter autentiseringsuppgifter):
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Credentials: true
Du mÄste ocksÄ stÀlla in credentials: 'include' i din JavaScript fetch/XMLHttpRequest-begÀran.
fetch('https://api.example.com/data', {
credentials: 'include'
})
CORS-förhandsbegÀranden
För vissa typer av korsursprungsbegÀranden (t.ex. begÀranden med anpassade huvuden eller metoder andra Àn GET, HEAD eller POST med Content-Type av application/x-www-form-urlencoded, multipart/form-data eller text/plain) skickar webblÀsaren en förhandsbegÀran med metoden OPTIONS. Servern mÄste svara pÄ förhandsbegÀran med lÀmpliga CORS-huvuden för att indikera om den faktiska begÀran Àr tillÄten.
HÀr Àr ett exempel pÄ en förhandsbegÀran och ett svar:
FörhandsbegÀran (OPTIONS):
OPTIONS /data HTTP/1.1
Origin: https://www.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type, Authorization
Förhandssvar (200 OK):
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
Huvudet Access-Control-Max-Age anger hur lÀnge webblÀsaren kan cachelagra förhandssvaret, vilket minskar antalet förhandsbegÀranden.
CORS och JSONP
JSON with Padding (JSONP) Àr en Àldre teknik för att kringgÄ Same-Origin Policy. JSONP har dock betydande sÀkerhetsrisker och bör undvikas till förmÄn för CORS. JSONP förlitar sig pÄ att injicera <script>-taggar pÄ sidan, vilket kan exekvera godtycklig kod. CORS ger ett sÀkrare och mer flexibelt sÀtt att hantera korsursprungsbegÀranden.
BÀsta metoder för CORS
- Undvik att anvÀnda *: Undvik att anvÀnda jokertecknet (*) i huvudet
Access-Control-Allow-Origin, eftersom det tillÄter begÀranden frÄn vilket ursprung som helst. Ange istÀllet de specifika ursprung som fÄr komma Ät resursen. - Var specifik med metoder och huvuden: Ange de exakta HTTP-metoder och huvuden som Àr tillÄtna i huvudena
Access-Control-Allow-MethodsochAccess-Control-Allow-Headers. - AnvÀnd Access-Control-Allow-Credentials med försiktighet: Aktivera endast
Access-Control-Allow-Credentialsom du behöver tillÄta autentiseringsuppgifter (t.ex. cookies) i korsursprungsbegÀranden. Var medveten om sÀkerhetsimplikationerna av att tillÄta autentiseringsuppgifter. - SÀkra dina förhandsbegÀranden: Se till att din server hanterar förhandsbegÀranden korrekt och returnerar rÀtt CORS-huvuden.
- AnvÀnd HTTPS: AnvÀnd alltid HTTPS för bÄde ursprunget och de resurser du kommer Ät korsursprung. Detta hjÀlper till att skydda mot man-in-the-middle-attacker.
- Vary: Origin: Om du dynamiskt genererar huvudet `Access-Control-Allow-Origin`, inkludera alltid huvudet `Vary: Origin` för att förhindra cachningsproblem.
CSP och CORS i praktiken: En kombinerad strategi
Ăven om CSP och CORS bĂ„da tar itu med sĂ€kerhetsproblem, fungerar de pĂ„ olika lager och ger kompletterande skydd. CSP fokuserar pĂ„ att förhindra att webblĂ€saren lĂ€ser in skadligt innehĂ„ll, medan CORS fokuserar pĂ„ att kontrollera vilka ursprung som kan komma Ă„t resurser pĂ„ din server.
Genom att kombinera CSP och CORS kan du skapa en mer robust sÀkerhetsposition för dina webbapplikationer. Du kan till exempel anvÀnda CSP för att begrÀnsa de kÀllor frÄn vilka skript kan lÀsas in, och CORS för att kontrollera vilka ursprung som kan komma Ät dina API-slutpunkter.
Exempel: SĂ€kra ett API med CSP och CORS
LÄt oss sÀga att du har ett API som finns pÄ https://api.example.com som du vill ska vara tillgÀngligt endast frÄn https://www.example.com. Du kan konfigurera din server att returnera följande huvuden:
API-responshuvuden (https://api.example.com):
Access-Control-Allow-Origin: https://www.example.com
Content-Type: application/json
Och du kan konfigurera din webbplats (https://www.example.com) att anvÀnda följande CSP-huvud:
Webbplatsens CSP-huvud (https://www.example.com):
Content-Security-Policy: default-src 'self'; script-src 'self'; connect-src 'self' https://api.example.com;
Denna CSP-policy tillÄter webbplatsen att lÀsa in skript och ansluta till API:et, men hindrar den frÄn att lÀsa in skript eller ansluta till andra domÀner.
Slutsats
Content Security Policy (CSP) och Cross-Origin Resource Sharing (CORS) Àr viktiga verktyg för att hÀrda sÀkerheten för dina frontend-applikationer. Genom att noggrant konfigurera CSP och CORS kan du avsevÀrt minska risken för XSS-attacker, datainjektionsattacker och andra sÀkerhetsproblem. Kom ihÄg att börja med en restriktiv policy, testa noggrant och kontinuerligt övervaka och förfina din konfiguration för att anpassa dig till förÀndringar i din applikation och det förÀnderliga hotlandskapet. Genom att prioritera frontend-sÀkerhet kan du skydda dina anvÀndare och sÀkerstÀlla integriteten hos dina webbapplikationer i dagens alltmer komplexa digitala vÀrld.