Išsamus vadovas, kaip pagerinti priekinės sąsajos saugumą naudojant turinio saugumo politiką (CSP) ir tarpšaltinių išteklių bendrinimą (CORS), apsaugant žiniatinklio programas nuo šiuolaikinių grėsmių.
Priekinės sąsajos saugumo stiprinimas: turinio saugumo politika ir CORS
Šiandieniniame tarpusavyje susijusiame skaitmeniniame pasaulyje priekinės sąsajos saugumas yra nepaprastai svarbus. Žiniatinklio programos vis dažniau tampa sudėtingų atakų taikiniu, todėl būtinos patikimos saugumo priemonės. Du svarbūs saugios priekinės sąsajos architektūros komponentai yra turinio saugumo politika (CSP) ir tarpšaltinių išteklių bendrinimas (CORS). Šis išsamus vadovas pateikia išsamų žvilgsnį į šias technologijas, siūlant praktinių pavyzdžių ir veiksmingų įžvalgų, padėsiančių apsaugoti žiniatinklio programas nuo šiuolaikinių grėsmių.
Kas yra turinio saugumo politika (CSP)?
Turinio saugumo politika (CSP) yra papildomas saugumo lygis, padedantis aptikti ir sumažinti tam tikrų tipų atakas, įskaitant tarpšaltinių scenarijų (XSS) ir duomenų įterpimo atakas. CSP įgyvendinama žiniatinklio serveriui siunčiant Content-Security-Policy HTTP atsakymo antraštę į naršyklę. Ši antraštė apibrėžia šaltinių, iš kurių naršyklei leidžiama įkelti išteklius, baltąjį sąrašą. Apribojant turinio šaltinius, kuriuos naršyklė gali įkelti, CSP labai apsunkina užpuolikams kenkėjiško kodo įterpimą į jūsų svetainę.
Kaip veikia CSP
CSP veikia nurodydama naršyklei įkelti tik išteklius (pvz., scenarijus, stilių aprašus, vaizdus, šriftus) iš patvirtintų šaltinių. Šie šaltiniai nurodomi CSP antraštėje naudojant direktyvas. Jei naršyklė bando įkelti išteklių iš šaltinio, kuris nėra aiškiai leidžiamas, ji blokuos užklausą ir praneš apie pažeidimą.
CSP direktyvos: išsami apžvalga
CSP direktyvos kontroliuoja išteklių tipus, kuriuos galima įkelti iš konkrečių šaltinių. Štai keletas svarbiausių direktyvų:
- default-src: Nurodo numatytąjį visų turinio tipų šaltinį. Tai atsarginė direktyva, taikoma, kai nėra kitų, konkretesnių direktyvų.
- script-src: Nurodo šaltinius, iš kurių galima įkelti scenarijus. Tai labai svarbu norint užkirsti kelią XSS atakoms.
- style-src: Nurodo šaltinius, iš kurių galima įkelti stilių aprašus.
- img-src: Nurodo šaltinius, iš kurių galima įkelti vaizdus.
- font-src: Nurodo šaltinius, iš kurių galima įkelti šriftus.
- media-src: Nurodo šaltinius, iš kurių galima įkelti garso ir vaizdo įrašus.
- object-src: Nurodo šaltinius, iš kurių galima įkelti įskiepius (pvz., Flash). Tai dažnai nustatoma į 'none', kad būtų visiškai išjungti įskiepiai dėl jų būdingos saugumo rizikos.
- frame-src: Nurodo šaltinius, iš kurių galima įkelti rėmus (pvz., <iframe>).
- connect-src: Nurodo URL, prie kurių vartotojo agentas gali prisijungti naudodamas scenarijų sąsajas, tokias kaip XMLHttpRequest, WebSocket ir EventSource.
- base-uri: Nurodo URL, kuriuos galima naudoti dokumento <base> elemente.
- form-action: Nurodo URL, į kuriuos galima siųsti formų pateikimus.
- upgrade-insecure-requests: Nurodo vartotojo agentui automatiškai atnaujinti nesaugias užklausas (HTTP) į saugias užklausas (HTTPS).
- report-uri: Nurodo URL, kur naršyklė turėtų siųsti ataskaitas apie CSP pažeidimus. Ši direktyva yra nebenaudojama, pirmenybę teikiant `report-to`.
- report-to: Nurodo ataskaitų teikimo grupės pavadinimą, apibrėžtą `Report-To` antraštėje, kur naršyklė turėtų siųsti ataskaitas apie CSP pažeidimus.
CSP šaltinių sąrašo raktažodžiai
CSP direktyvose galite naudoti šaltinių sąrašo raktažodžius, kad apibrėžtumėte leistinus šaltinius. Štai keletas dažniausiai pasitaikančių raktažodžių:
- 'self': Leidžia išteklius iš tos pačios kilmės (schemos ir pagrindinio kompiuterio), kaip ir dokumentas.
- 'none': Draudžia išteklius iš visų šaltinių.
- 'unsafe-inline': Leidžia naudoti įdėtuosius scenarijus ir stilius (pvz., <script> žymes ir stiliaus atributus). Naudokite labai atsargiai, nes tai labai susilpnina CSP apsaugą nuo XSS.
- 'unsafe-eval': Leidžia naudoti dinamines kodo įvertinimo funkcijas, tokias kaip
eval()irFunction(). Naudokite labai atsargiai, nes tai sukelia didelę saugumo riziką. - 'unsafe-hashes': Leidžia konkrečius įdėtuosius įvykių apdorojimo įrankius arba <style> žymes, atitinkančias nurodytą maišos kodą. Reikalingas naršyklės palaikymas. Naudokite atsargiai.
- 'strict-dynamic': Nurodo, kad pasitikėjimas, aiškiai suteiktas scenarijui, esančiam žymėjime, pridedant nonce arba maišos kodą, turi būti perduotas visiems scenarijams, įkeltiems to pagrindinio scenarijaus.
- data: Leidžia data: URI (pvz., įdėtieji vaizdai, užkoduoti kaip base64). Naudokite atsargiai.
- https:: Leidžia įkelti išteklius per HTTPS iš bet kurio domeno.
- [hostname]: Leidžia išteklius iš konkretaus domeno (pvz., example.com). Taip pat galite nurodyti prievado numerį (pvz., example.com:8080).
- [scheme]://[hostname]:[port]: Visiškai kvalifikuotas URI, leidžiantis išteklius iš nurodytos schemos, pagrindinio kompiuterio ir prievado.
Praktiniai CSP pavyzdžiai
Pažvelkime į keletą praktinių CSP antraščių pavyzdžių:
1 pavyzdys: pagrindinis CSP su 'self'
Ši politika leidžia išteklius tik iš tos pačios kilmės:
Content-Security-Policy: default-src 'self'
2 pavyzdys: scenarijų leidimas iš konkretaus domeno
Ši politika leidžia scenarijus iš jūsų pačių domeno ir patikimo CDN:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com
3 pavyzdys: įdėtųjų scenarijų ir stilių išjungimas
Ši politika neleidžia įdėtųjų scenarijų ir stilių, o tai yra stipri gynyba nuo XSS:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'
Svarbu: Norint išjungti įdėtuosius scenarijus, reikia performatuoti HTML, kad įdėtieji scenarijai būtų perkelti į išorinius failus.
4 pavyzdys: Nonces naudojimas įdėtiesiems scenarijams
Jei turite naudoti įdėtuosius scenarijus, naudokite nonces (kriptografiškai atsitiktinius, vienkartinius žetonus), kad įtrauktumėte konkrečius įdėtuosius scenarijų blokus į baltąjį sąrašą. Tai yra saugiau nei 'unsafe-inline'. Serveris turi generuoti unikalų nonce kiekvienai užklausai ir įtraukti jį į CSP antraštę ir <script> žymą.
Content-Security-Policy: default-src 'self'; script-src 'nonce-r4nd0mN0nc3'; style-src 'self'
<script nonce="r4nd0mN0nc3"> console.log('Inline script'); </script>
Pastaba: Nepamirškite generuoti naujo nonce kiekvienai užklausai. Nenaudokite nonce pakartotinai!
5 pavyzdys: maišos kodo naudojimas įdėtiesiems stiliams
Panašiai kaip ir nonces, maišos kodus galima naudoti norint įtraukti konkrečius įdėtuosius <style> blokus į baltąjį sąrašą. Tai daroma generuojant SHA256, SHA384 arba SHA512 stiliaus turinio maišos kodą.
Content-Security-Policy: default-src 'self'; style-src 'sha256-HASHEDSTYLES'
<style sha256="HASHEDSTYLES"> body { background-color: #f0f0f0; } </style>
Pastaba: Maišos kodai yra mažiau lankstūs nei nonces, nes bet koks stiliaus turinio pakeitimas anuliuos maišos kodą.
6 pavyzdys: CSP pažeidimų ataskaitų teikimas
Norėdami stebėti CSP pažeidimus, naudokite report-uri arba report-to direktyvą:
Content-Security-Policy: default-src 'self'; report-to csp-endpoint;
Taip pat turėsite sukonfigūruoti Report-To antraštę. Report-To antraštė apibrėžia vieną ar daugiau ataskaitų teikimo grupių, kurios nurodo, kur ir kaip turėtų būti siunčiamos ataskaitos.
Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"https://example.com/csp-report"}]}
CSP testavimas ir diegimas
CSP įgyvendinimas reikalauja kruopštaus planavimo ir testavimo. Pradėkite nuo ribojančios politikos ir palaipsniui ją atlaisvinkite, jei reikia. Naudokite Content-Security-Policy-Report-Only antraštę, kad išbandytumėte savo politiką neblokuodami išteklių. Ši antraštė praneša apie pažeidimus neįgyvendindama politikos, todėl galite nustatyti ir išspręsti problemas prieš diegiant politiką gamyboje.
Content-Security-Policy-Report-Only: default-src 'self'; report-to csp-endpoint;
Analizuokite naršyklės sukurtas ataskaitas, kad nustatytumėte bet kokius pažeidimus ir atitinkamai pakoreguotumėte savo politiką. Kai esate įsitikinę, kad jūsų politika veikia tinkamai, įdiekite ją naudodami Content-Security-Policy antraštę.
Geriausios CSP praktikos
- Pradėkite nuo default-src: Visada apibrėžkite
default-src, kad nustatytumėte pagrindinę politiką. - Būkite konkretūs: Naudokite konkrečias direktyvas ir šaltinių sąrašo raktažodžius, kad apribotumėte savo politikos taikymo sritį.
- Venkite 'unsafe-inline' ir 'unsafe-eval': Šie raktažodžiai labai susilpnina CSP ir reikėtų jų vengti, kai tik įmanoma.
- Naudokite nonces arba maišos kodus įdėtiesiems scenarijams ir stiliams: Jei turite naudoti įdėtuosius scenarijus arba stilius, naudokite nonces arba maišos kodus, kad įtrauktumėte konkrečius kodo blokus į baltąjį sąrašą.
- Stebėkite CSP pažeidimus: Naudokite
report-uriarbareport-todirektyvą, kad stebėtumėte CSP pažeidimus ir atitinkamai pakoreguotumėte savo politiką. - Kruopščiai išbandykite: Naudokite
Content-Security-Policy-Report-Onlyantraštę, kad išbandytumėte savo politiką prieš diegiant ją gamyboje. - Iteruokite ir tobulinkite: CSP nėra vienkartinė konfigūracija. Nuolat stebėkite ir tobulinkite savo politiką, kad prisitaikytumėte prie jūsų programos pokyčių ir grėsmių aplinkos.
Kas yra tarpšaltinių išteklių bendrinimas (CORS)?
Tarpšaltinių išteklių bendrinimas (CORS) yra mechanizmas, leidžiantis žiniatinklio puslapiams iš vienos kilmės (domeno) pasiekti išteklius iš skirtingos kilmės. Pagal numatytuosius nustatymus naršyklės įgyvendina tos pačios kilmės politiką, kuri neleidžia scenarijams teikti užklausų į kitą kilmę nei ta, iš kurios scenarijus kilo. CORS suteikia būdą selektyviai sušvelninti šį apribojimą, leidžiant teisėtas tarpšaltinių užklausas ir apsaugant nuo kenkėjiškų atakų.
Tos pačios kilmės politikos supratimas
Tos pačios kilmės politika yra pagrindinis saugumo mechanizmas, kuris neleidžia kenkėjiškam scenarijui iš vienos svetainės pasiekti slaptus duomenis kitoje svetainėje. Kilmė apibrėžiama schema (protokolu), pagrindiniu kompiuteriu (domenu) ir prievadu. Du URL turi tą pačią kilmę, jei ir tik jei jie turi tą pačią schemą, pagrindinį kompiuterį ir prievadą.
Pavyzdžiui:
https://www.example.com/app1/index.htmlirhttps://www.example.com/app2/index.htmlturi tą pačią kilmę.https://www.example.com/index.htmlirhttp://www.example.com/index.htmlturi skirtingas kilmes (skirtinga schema).https://www.example.com/index.htmlirhttps://sub.example.com/index.htmlturi skirtingas kilmes (skirtingas pagrindinis kompiuteris).https://www.example.com:8080/index.htmlirhttps://www.example.com:80/index.htmlturi skirtingas kilmes (skirtingas prievadas).
Kaip veikia CORS
Kai žiniatinklio puslapis pateikia tarpšaltinių užklausą, naršyklė pirmiausia siunčia „preflight“ užklausą į serverį. „Preflight“ užklausa naudoja HTTP OPTIONS metodą ir apima antraštes, nurodančias HTTP metodą ir antraštes, kurias naudos faktinė užklausa. Tada serveris atsako antraštėmis, nurodančiomis, ar tarpšaltinių užklausa yra leidžiama.
Jei serveris leidžia užklausą, jis į atsakymą įtraukia Access-Control-Allow-Origin antraštę. Ši antraštė nurodo kilmę (-is), kuriai (-oms) leidžiama pasiekti išteklių. Tada naršyklė tęsia faktinę užklausą. Jei serveris neleidžia užklausos, jis neįtraukia Access-Control-Allow-Origin antraštės, o naršyklė blokuoja užklausą.
CORS antraštės: išsamus žvilgsnis
CORS remiasi HTTP antraštėmis, kad bendrautų tarp naršyklės ir serverio. Štai pagrindinės CORS antraštės:
- Access-Control-Allow-Origin: Nurodo kilmę (-is), kuriai (-oms) leidžiama pasiekti išteklių. Ši antraštė gali turėti konkrečią kilmę (pvz.,
https://www.example.com), pakaitos simbolį (*) arbanull.*naudojimas leidžia užklausas iš bet kurios kilmės, o tai paprastai nerekomenduojama dėl saugumo priežasčių.nullnaudojimas tinka tik „neskaidriems atsakymams“, pvz., kai išteklius gaunamas naudojantfile://protokolą arba data URI. - Access-Control-Allow-Methods: Nurodo HTTP metodus, kurie yra leidžiami tarpšaltinių užklausai (pvz.,
GET, POST, PUT, DELETE). - Access-Control-Allow-Headers: Nurodo HTTP antraštes, kurios yra leidžiamos tarpšaltinių užklausoje. Tai svarbu tvarkant pasirinktines antraštes.
- Access-Control-Allow-Credentials: Nurodo, ar naršyklė turėtų įtraukti kredencialus (pvz., slapukus, autorizacijos antraštes) į tarpšaltinių užklausą. Ši antraštė turi būti nustatyta į
true, kad būtų leista naudoti kredencialus. - Access-Control-Expose-Headers: Nurodo, kurios antraštės gali būti atskleistos klientui. Pagal numatytuosius nustatymus atskleidžiama tik ribota antraščių grupė.
- Access-Control-Max-Age: Nurodo didžiausią laiką (sekundėmis), kiek naršyklė gali talpykloje saugoti „preflight“ užklausą.
- Origin: Tai užklausos antraštė, kurią siunčia naršyklė, kad nurodytų užklausos kilmę.
- Vary: Bendra HTTP antraštė, bet svarbi CORS. Kai
Access-Control-Allow-Origingeneruojama dinamiškai,Vary: Originantraštė turėtų būti įtraukta į atsakymą, kad talpyklos mechanizmai būtų informuoti, jog atsakymas skiriasi priklausomai nuoOriginužklausos antraštės.
Praktiniai CORS pavyzdžiai
Pažvelkime į keletą praktinių CORS konfigūracijų pavyzdžių:
1 pavyzdys: užklausų leidimas iš konkrečios kilmės
Ši konfigūracija leidžia užklausas tik iš https://www.example.com:
Access-Control-Allow-Origin: https://www.example.com
2 pavyzdys: užklausų leidimas iš bet kurios kilmės (nerekomenduojama)
Ši konfigūracija leidžia užklausas iš bet kurios kilmės. Naudokite atsargiai, nes tai gali sukelti saugumo riziką:
Access-Control-Allow-Origin: *
3 pavyzdys: konkrečių metodų ir antraščių leidimas
Ši konfigūracija leidžia GET, POST ir PUT metodus ir Content-Type bei Authorization antraštes:
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
4 pavyzdys: kredencialų leidimas
Norėdami leisti naudoti kredencialus (pvz., slapukus), turite nustatyti Access-Control-Allow-Credentials į true ir nurodyti konkrečią kilmę (negali naudoti *, kai leidžiate naudoti kredencialus):
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Credentials: true
Taip pat turite nustatyti credentials: 'include' savo JavaScript fetch/XMLHttpRequest užklausoje.
fetch('https://api.example.com/data', {
credentials: 'include'
})
CORS „Preflight“ užklausos
Tam tikrų tipų tarpšaltinių užklausoms (pvz., užklausoms su pasirinktinėmis antraštėmis arba metodais, kitais nei GET, HEAD arba POST su Content-Type iš application/x-www-form-urlencoded, multipart/form-data arba text/plain), naršyklė siunčia „preflight“ užklausą naudodama OPTIONS metodą. Serveris turi atsakyti į „preflight“ užklausą su atitinkamomis CORS antraštėmis, kad nurodytų, ar faktinė užklausa yra leidžiama.
Štai „preflight“ užklausos ir atsakymo pavyzdys:
„Preflight“ užklausa (OPTIONS):
OPTIONS /data HTTP/1.1
Origin: https://www.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type, Authorization
„Preflight“ atsakymas (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
Access-Control-Max-Age antraštė nurodo, kiek laiko naršyklė gali talpykloje saugoti „preflight“ atsakymą, sumažindama „preflight“ užklausų skaičių.
CORS ir JSONP
JSON su užpildymu (JSONP) yra senesnė technika, skirta apeiti tos pačios kilmės politiką. Tačiau JSONP turi didelę saugumo riziką ir reikėtų jo vengti, pirmenybę teikiant CORS. JSONP remiasi <script> žymių įterpimu į puslapį, kuris gali vykdyti savavališką kodą. CORS suteikia saugesnį ir lankstesnį būdą tvarkyti tarpšaltinių užklausas.
Geriausios CORS praktikos
- Venkite naudoti *: Venkite naudoti pakaitos simbolį (*)
Access-Control-Allow-Originantraštėje, nes tai leidžia užklausas iš bet kurios kilmės. Vietoj to nurodykite konkrečią (-ias) kilmę (-is), kuriai (-oms) leidžiama pasiekti išteklių. - Būkite konkretūs su metodais ir antraštėmis: Nurodykite tikslius HTTP metodus ir antraštes, kurios yra leidžiamos
Access-Control-Allow-MethodsirAccess-Control-Allow-Headersantraštėse. - Naudokite Access-Control-Allow-Credentials atsargiai: Įjunkite
Access-Control-Allow-Credentialstik tuo atveju, jei jums reikia leisti naudoti kredencialus (pvz., slapukus) tarpšaltinių užklausose. Žinokite apie saugumo pasekmes, susijusias su kredencialų leidimu. - Apsaugokite savo „preflight“ užklausas: Įsitikinkite, kad jūsų serveris tinkamai tvarko „preflight“ užklausas ir grąžina teisingas CORS antraštes.
- Naudokite HTTPS: Visada naudokite HTTPS tiek kilmei, tiek ištekliams, kuriuos pasiekiate tarpkilminiu būdu. Tai padeda apsisaugoti nuo žmogaus įsibrovimo atakų.
- Vary: Origin: Jei dinamiškai generuojate
Access-Control-Allow-Originantraštę, visada įtraukiteVary: Originantraštę, kad išvengtumėte talpyklos problemų.
CSP ir CORS praktikoje: kombinuotas požiūris
Nors CSP ir CORS sprendžia saugumo problemas, jie veikia skirtinguose lygiuose ir suteikia papildomą apsaugą. CSP daugiausia dėmesio skiria tam, kad naršyklė neįkeltų kenkėjiško turinio, o CORS daugiausia dėmesio skiria tam, kad būtų kontroliuojama, kurios kilmės gali pasiekti išteklius jūsų serveryje.
Derindami CSP ir CORS, galite sukurti tvirtesnę savo žiniatinklio programų saugumo padėtį. Pavyzdžiui, galite naudoti CSP, kad apribotumėte šaltinius, iš kurių galima įkelti scenarijus, ir CORS, kad kontroliuotumėte, kurios kilmės gali pasiekti jūsų API galinius taškus.
Pavyzdys: API apsauga naudojant CSP ir CORS
Tarkime, kad turite API, patalpintą adresu https://api.example.com, kurią norite pasiekti tik iš https://www.example.com. Galite sukonfigūruoti savo serverį, kad jis grąžintų šias antraštes:
API atsakymo antraštės (https://api.example.com):
Access-Control-Allow-Origin: https://www.example.com
Content-Type: application/json
Ir galite sukonfigūruoti savo svetainę (https://www.example.com), kad ji naudotų šią CSP antraštę:
Svetainės CSP antraštė (https://www.example.com):
Content-Security-Policy: default-src 'self'; script-src 'self'; connect-src 'self' https://api.example.com;
Ši CSP politika leidžia svetainei įkelti scenarijus ir prisijungti prie API, bet neleidžia jai įkelti scenarijų arba prisijungti prie kitų domenų.
Išvada
Turinio saugumo politika (CSP) ir tarpšaltinių išteklių bendrinimas (CORS) yra esminiai įrankiai, skirti sustiprinti jūsų priekinės sąsajos programų saugumą. Kruopščiai sukonfigūravę CSP ir CORS, galite žymiai sumažinti XSS atakų, duomenų įterpimo atakų ir kitų saugumo pažeidžiamumų riziką. Atminkite, kad reikia pradėti nuo ribojančios politikos, kruopščiai išbandyti ir nuolat stebėti bei tobulinti savo konfigūraciją, kad prisitaikytumėte prie jūsų programos pokyčių ir besikeičiančios grėsmių aplinkos. Teikdami pirmenybę priekinės sąsajos saugumui, galite apsaugoti savo vartotojus ir užtikrinti savo žiniatinklio programų vientisumą šiandieniniame vis sudėtingesniame skaitmeniniame pasaulyje.