Podrobné preskúmanie zdieľania zdrojov medzi rôznymi doménami (CORS) a pre-flight požiadaviek. Naučte sa, ako riešiť problémy s CORS a zabezpečiť svoje webové aplikácie pre globálne publikum.
Objasnenie CORS: Hĺbkový ponor do spracovania pre-flight požiadaviek v jazyku JavaScript
V neustále sa rozširujúcom svete vývoja webu je bezpečnosť prvoradá. Zdieľanie zdrojov medzi rôznymi doménami (CORS) je kľúčový bezpečnostný mechanizmus implementovaný webovými prehliadačmi na obmedzenie webových stránok pri vytváraní požiadaviek na inú doménu, ako je tá, ktorá webovú stránku obsluhovala. Ide o základnú bezpečnostnú funkciu, ktorej cieľom je zabrániť škodlivým webovým stránkam v prístupe k citlivým údajom. Táto komplexná príručka sa ponorí do zložitosti CORS so zameraním špecificky na spracovanie pre-flight požiadaviek. Preskúmame „prečo“, „čo“ a „ako“ CORS a poskytneme praktické príklady a riešenia bežných problémov, s ktorými sa stretávajú vývojári na celom svete.
Pochopenie politiky rovnakého pôvodu
V srdci CORS leží Politika rovnakého pôvodu (SOP). Táto politika je bezpečnostný mechanizmus na úrovni prehliadača, ktorý obmedzuje skripty spúšťané na jednom pôvode v prístupe k zdrojom z iného pôvodu. Pôvod je definovaný protokolom (napr. HTTP alebo HTTPS), doménou (napr. example.com) a portom (napr. 80 alebo 443). Dve adresy URL majú rovnaký pôvod, ak sa tieto tri komponenty presne zhodujú.
Napríklad:
https://www.example.com/app1/index.htmlahttps://www.example.com/app2/index.htmlmajú rovnaký pôvod (rovnaký protokol, doména a port).https://www.example.com/index.htmlahttp://www.example.com/index.htmlmajú rôzne pôvody (rôzne protokoly).https://www.example.com/index.htmlahttps://api.example.com/index.htmlmajú rôzne pôvody (rôzne subdomény sa považujú za rôzne domény).https://www.example.com:8080/index.htmlahttps://www.example.com/index.htmlmajú rôzne pôvody (rôzne porty).
SOP je navrhnutá tak, aby zabránila škodlivým skriptom na jednej webovej stránke v prístupe k citlivým údajom, ako sú súbory cookie alebo informácie o autentifikácii používateľa, na inej webovej stránke. Hoci je SOP nevyhnutná pre bezpečnosť, môže byť aj obmedzujúca, najmä ak sú potrebné legitímne požiadavky medzi rôznymi pôvodmi.
Čo je zdieľanie zdrojov medzi rôznymi doménami (CORS)?
CORS je mechanizmus, ktorý umožňuje serverom špecifikovať, ktoré pôvody (domény, schémy alebo porty) majú povolený prístup k ich zdrojom. V podstate uvoľňuje SOP a umožňuje kontrolovaný prístup medzi rôznymi pôvodmi. CORS sa implementuje pomocou hlavičiek HTTP, ktoré sa vymieňajú medzi klientom (zvyčajne webovým prehliadačom) a serverom.
Keď prehliadač vytvorí požiadavku medzi rôznymi pôvodmi (t. j. požiadavku na iný pôvod, ako je aktuálna stránka), najprv skontroluje, či server túto požiadavku povoľuje. To sa vykoná preskúmaním hlavičky Access-Control-Allow-Origin v odpovedi servera. Ak je pôvod požiadavky uvedený v tejto hlavičke (alebo ak je hlavička nastavená na *, čo umožňuje všetky pôvody), prehliadač umožní pokračovanie požiadavky. V opačnom prípade prehliadač požiadavku zablokuje, čím zabráni kódu JavaScript v prístupe k údajom odpovede.
Úloha pre-flight požiadaviek
Pre určité typy požiadaviek medzi rôznymi pôvodmi prehliadač iniciuje pre-flight požiadavku. Ide o požiadavku OPTIONS odoslanú na server pred skutočnou požiadavkou. Účelom pre-flight požiadavky je určiť, či je server ochotný prijať skutočnú požiadavku. Server odpovedá na pre-flight požiadavku informáciami o povolených metódach, hlavičkách a iných obmedzeniach.
Pre-flight požiadavky sa spúšťajú, keď požiadavka medzi rôznymi pôvodmi spĺňa ktorúkoľvek z nasledujúcich podmienok:
- Metóda požiadavky nie je
GET,HEADaleboPOST. - Požiadavka obsahuje vlastné hlavičky (t. j. hlavičky iné ako tie, ktoré prehliadač automaticky pridáva).
- Hlavička
Content-Typeje nastavená na čokoľvek iné akoapplication/x-www-form-urlencoded,multipart/form-dataalebotext/plain. - Požiadavka používa objekty
ReadableStreamv tele.
Napríklad, požiadavka PUT s Content-Type application/json spustí pre-flight požiadavku, pretože používa inú metódu ako povolené a potenciálne nepovolený typ obsahu.
Prečo pre-flight požiadavky?
Pre-flight požiadavky sú nevyhnutné pre bezpečnosť, pretože poskytujú serveru príležitosť odmietnuť potenciálne škodlivé požiadavky medzi rôznymi pôvodmi predtým, ako sa vykonajú. Bez pre-flight požiadaviek by škodlivá webová stránka mohla potenciálne odosielať ľubovoľné požiadavky na server bez výslovného súhlasu servera. Pre-flight požiadavka umožňuje serveru overiť, či je požiadavka prijateľná, a zabráni potenciálne škodlivým operáciám.
Spracovanie pre-flight požiadaviek na strane servera
Správne spracovanie pre-flight požiadaviek je rozhodujúce pre zabezpečenie správneho a bezpečného fungovania vašej webovej aplikácie. Server musí odpovedať na požiadavku OPTIONS s príslušnými hlavičkami CORS, aby určil, či je skutočná požiadavka povolená.
Tu je rozpis kľúčových hlavičiek CORS, ktoré sa používajú v pre-flight odpovediach:
Access-Control-Allow-Origin: Táto hlavička špecifikuje pôvody, ktoré majú povolený prístup k zdroju. Môže byť nastavená na konkrétny pôvod (napr.https://www.example.com) alebo na*, aby povolila všetky pôvody. Používanie*sa však vo všeobecnosti neodporúča z bezpečnostných dôvodov, najmä ak server spracováva citlivé údaje.Access-Control-Allow-Methods: Táto hlavička špecifikuje metódy HTTP, ktoré sú povolené pre požiadavku medzi rôznymi pôvodmi (napr.GET,POST,PUT,DELETE).Access-Control-Allow-Headers: Táto hlavička špecifikuje zoznam neštandardných hlavičiek HTTP, ktoré sú povolené v skutočnej požiadavke. Je to potrebné, ak klient odosiela vlastné hlavičky, ako napríkladX-Custom-HeaderaleboAuthorization.Access-Control-Allow-Credentials: Táto hlavička označuje, či skutočná požiadavka môže obsahovať poverenia, ako sú súbory cookie alebo autorizačné hlavičky. Musí byť nastavená natrue, ak kód na strane klienta odosiela poverenia a server by ich mal prijať. Poznámka: keď je táto hlavička nastavená na `true`, `Access-Control-Allow-Origin` *nemôže* byť nastavená na `*`. Musíte zadať pôvod.Access-Control-Max-Age: Táto hlavička špecifikuje maximálny čas (v sekundách), počas ktorého môže prehliadač ukladať pre-flight odpoveď do vyrovnávacej pamäte. To môže pomôcť zlepšiť výkon znížením počtu odoslaných pre-flight požiadaviek.
Príklad: Spracovanie pre-flight požiadaviek v Node.js s Express
Tu je príklad, ako spracovať pre-flight požiadavky v aplikácii Node.js pomocou rámca Express:
const express = require('express');
const cors = require('cors');
const app = express();
// Enable CORS for all origins (for development purposes only!)
// In production, specify allowed origins for better security.
app.use(cors()); //or app.use(cors({origin: 'https://www.example.com'}));
// Route for handling OPTIONS requests (preflight)
app.options('/data', cors()); // Enable CORS for a single route. Or specify origin: cors({origin: 'https://www.example.com'})
// Route for handling GET requests
app.get('/data', (req, res) => {
res.json({ message: 'This is cross-origin data!' });
});
// Route to handle a preflight and a post request
app.options('/resource', cors()); // enable pre-flight request for DELETE request
app.delete('/resource', cors(), (req, res, next) => {
res.send('delete resource')
})
const port = 3000;
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
V tomto príklade používame middleware cors na spracovanie požiadaviek CORS. Pre podrobnejšiu kontrolu je možné CORS povoliť pre každú trasu zvlášť. Poznámka: v produkčnom prostredí sa dôrazne odporúča špecifikovať povolené pôvody pomocou možnosti origin namiesto povolenia všetkých pôvodov. Povolenie všetkých pôvodov pomocou * môže vystaviť vašu aplikáciu bezpečnostným zraniteľnostiam.
Príklad: Spracovanie pre-flight požiadaviek v Pythone s Flask
Tu je príklad, ako spracovať pre-flight požiadavky v aplikácii Python pomocou rámca Flask a rozšírenia flask_cors:
from flask import Flask, jsonify
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app) # Enable CORS for all routes
@app.route('/data')
@cross_origin()
def get_data():
data = {"message": "This is cross-origin data!"}
return jsonify(data)
if __name__ == '__main__':
app.run(debug=True)
Toto je najjednoduchšie použitie. Ako už bolo spomenuté, pôvody je možné obmedziť. Podrobnosti nájdete v dokumentácii flask-cors.
Príklad: Spracovanie pre-flight požiadaviek v jazyku Java s Spring Boot
Tu je príklad, ako spracovať pre-flight požiadavky v aplikácii Java pomocou Spring Boot:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@SpringBootApplication
public class CorsApplication {
public static void main(String[] args) {
SpringApplication.run(CorsApplication.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/data").allowedOrigins("http://localhost:8080");
}
};
}
}
A zodpovedajúci kontrolér:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DataController {
@GetMapping("/data")
public String getData() {
return "This is cross-origin data!";
}
}
Bežné problémy CORS a riešenia
Napriek svojmu významu môže byť CORS často zdrojom frustrácie pre vývojárov. Tu sú niektoré bežné problémy CORS a ich riešenia:
-
Chyba: „Na požadovanom zdroji nie je prítomná hlavička Access-Control-Allow-Origin.“
Táto chyba znamená, že server nevracia hlavičku
Access-Control-Allow-Originvo svojej odpovedi. Ak to chcete opraviť, uistite sa, že server je nakonfigurovaný tak, aby obsahoval hlavičku a že je nastavená na správny pôvod alebo na*(ak je to vhodné).Riešenie: Nakonfigurujte server tak, aby zahrnul hlavičku `Access-Control-Allow-Origin` vo svojej odpovedi, pričom ju nastavte na pôvod požadujúcej webovej stránky alebo na `*` na povolenie všetkých pôvodov (používajte opatrne).
-
Chyba: „Odpoveď na pre-flight požiadavku neprejde kontrolou riadenia prístupu: Požadované pole hlavičky X-Custom-Header nie je povolené pomocou Access-Control-Allow-Headers v pre-flight odpovedi.“
Táto chyba znamená, že server nepovoľuje vlastnú hlavičku (
X-Custom-Headerv tomto príklade) v požiadavke medzi rôznymi pôvodmi. Ak to chcete opraviť, uistite sa, že server obsahuje hlavičku v hlavičkeAccess-Control-Allow-Headersv pre-flight odpovedi.Riešenie: Pridajte vlastnú hlavičku (napr. `X-Custom-Header`) do hlavičky `Access-Control-Allow-Headers` v pre-flight odpovedi servera.
-
Chyba: „Príznak poverení je „true“, ale hlavička Access-Control-Allow-Origin je „*“.“
Keď je hlavička
Access-Control-Allow-Credentialsnastavená natrue, hlavičkaAccess-Control-Allow-Originmusí byť nastavená na konkrétny pôvod, nie na*. Je to preto, že povolenie poverení zo všetkých pôvodov by bolo bezpečnostným rizikom.Riešenie: Pri používaní poverení nastavte `Access-Control-Allow-Origin` na konkrétny pôvod namiesto `*`.
-
Pre-flight požiadavka sa neodosiela.
Skontrolujte, či kód Javascript obsahuje vlastnosť `credentials: 'include'`. Tiež skontrolujte, či váš server povoľuje `Access-Control-Allow-Credentials: true`.
-
Konfliktné konfigurácie medzi serverom a klientom.
Starostlivo skontrolujte konfiguráciu CORS na strane servera spolu s nastaveniami na strane klienta. Nesúlady (napr. server povoľuje iba požiadavky GET, ale klient odosiela POST) spôsobia chyby CORS.
CORS a osvedčené postupy zabezpečenia
Hoci CORS umožňuje kontrolovaný prístup medzi rôznymi pôvodmi, je nevyhnutné dodržiavať osvedčené postupy zabezpečenia, aby sa predišlo zraniteľnostiam:
- Vyhnite sa používaniu
*v hlavičkeAccess-Control-Allow-Originv produkčnom prostredí. To umožňuje všetkým pôvodom prístup k vašim zdrojom, čo môže predstavovať bezpečnostné riziko. Namiesto toho zadajte presné povolené pôvody. - Starostlivo zvážte, ktoré metódy a hlavičky povoliť. Povoľte iba metódy a hlavičky, ktoré sú nevyhnutne potrebné na správne fungovanie vašej aplikácie.
- Implementujte správne mechanizmy autentifikácie a autorizácie. CORS nie je náhradou za autentifikáciu a autorizáciu. Uistite sa, že vaše API je chránené vhodnými bezpečnostnými opatreniami.
- Overte a očistite všetky vstupy používateľa. To pomáha predchádzať útokom skriptovania medzi stránkami (XSS) a iným zraniteľnostiam.
- Udržiavajte aktualizovanú konfiguráciu CORS na strane servera. Pravidelne kontrolujte a aktualizujte konfiguráciu CORS, aby ste zabezpečili, že je v súlade s bezpečnostnými požiadavkami vašej aplikácie.
CORS v rôznych vývojových prostrediach
Problémy s CORS sa môžu prejavovať odlišne v rôznych vývojových prostrediach a technológiách. Tu je pohľad na to, ako pristupovať k CORS v niekoľkých bežných scenároch:
Lokálne vývojové prostredia
Počas lokálneho vývoja môžu byť problémy s CORS obzvlášť nepríjemné. Prehliadače často blokujú požiadavky z vášho lokálneho vývojového servera (napr. localhost:3000) na vzdialené API. Niekoľko techník môže zmierniť túto bolesť:
- Rozšírenia prehliadača: Rozšírenia ako „Allow CORS: Access-Control-Allow-Origin“ môžu dočasne zakázať obmedzenia CORS na testovacie účely. Nikdy ich však nepoužívajte v produkčnom prostredí.
- Proxy servery: Nakonfigurujte proxy server, ktorý preposiela požiadavky z vášho lokálneho vývojového servera na vzdialené API. To efektívne robí požiadavky „rovnakého pôvodu“ z pohľadu prehliadača. Nástroje ako
http-proxy-middleware(pre Node.js) sú na to užitočné. - Konfigurácia servera CORS: Aj počas vývoja je najlepšie nakonfigurovať server API tak, aby výslovne povoľoval požiadavky z vášho lokálneho vývojového pôvodu (napr.
http://localhost:3000). To simuluje konfiguráciu CORS v reálnom svete a pomáha vám zachytiť problémy včas.
Prostredia bez servera (napr. AWS Lambda, Google Cloud Functions)
Funkcie bez servera často vyžadujú starostlivú konfiguráciu CORS. Mnohé platformy bez servera poskytujú vstavanú podporu CORS, ale je dôležité ju správne nakonfigurovať:
- Nastavenia špecifické pre platformu: Použite vstavané možnosti konfigurácie CORS platformy. AWS Lambda napríklad umožňuje zadávať povolené pôvody, metódy a hlavičky priamo v nastaveniach API Gateway.
- Middleware/Knižnice: Pre väčšiu flexibilitu môžete použiť middleware alebo knižnice na spracovanie CORS v rámci kódu funkcie bez servera. To je podobné prístupom používaným v tradičných serverových prostrediach (napr. použitie balíka
corsvo funkciách Node.js Lambda). - Zvážte metódu `OPTIONS`: Uistite sa, že vaša funkcia bez servera správne spracováva požiadavky
OPTIONS. To často zahŕňa vytvorenie samostatnej trasy, ktorá vracia príslušné hlavičky CORS.
Vývoj mobilných aplikácií (napr. React Native, Flutter)
CORS je menej priamym problémom pre natívne mobilné aplikácie (Android, iOS), pretože zvyčajne nevynucujú politiku rovnakého pôvodu rovnakým spôsobom ako webové prehliadače. CORS však môže byť stále relevantný, ak vaša mobilná aplikácia používa webové zobrazenie na zobrazenie webového obsahu alebo ak používate rámce ako React Native alebo Flutter, ktoré využívajú JavaScript:
- Webové zobrazenia: Ak vaša mobilná aplikácia používa webové zobrazenie na zobrazenie webového obsahu, platia rovnaké pravidlá CORS ako vo webovom prehliadači. Nakonfigurujte server tak, aby povoľoval požiadavky z pôvodu webového obsahu.
- React Native/Flutter: Tieto rámce používajú JavaScript na vytváranie požiadaviek API. Hoci natívne prostredie nemusí vynucovať CORS priamo, základní klienti HTTP (napr.
fetch) môžu v určitých situáciách stále vykazovať správanie podobné CORS. - Natívni klienti HTTP: Pri vytváraní požiadaviek API priamo z natívneho kódu (napr. pomocou OkHttp na Androide alebo URLSession na iOS) CORS vo všeobecnosti nie je faktorom. Stále však musíte zvážiť osvedčené postupy zabezpečenia, ako sú správna autentifikácia a autorizácia.
Globálne aspekty konfigurácie CORS
Pri konfigurácii CORS pre globálne prístupnú aplikáciu je rozhodujúce zvážiť faktory ako:
- Dátová suverenita: Nariadenia v niektorých regiónoch vyžadujú, aby sa dáta nachádzali v danom regióne. CORS môže byť zapojený pri prístupe k zdrojom cez hranice, čo môže potenciálne porušovať zákony o dátovej rezidencii.
- Regionálne bezpečnostné politiky: Rôzne krajiny môžu mať odlišné predpisy a usmernenia v oblasti kybernetickej bezpečnosti, ktoré ovplyvňujú spôsob, akým by sa mal CORS implementovať a zabezpečiť.
- Siete pre doručovanie obsahu (CDN): Uistite sa, že vaša CDN je správne nakonfigurovaná na prenos potrebných hlavičiek CORS. Nesprávne nakonfigurované CDN môžu odstrániť hlavičky CORS, čo vedie k neočakávaným chybám.
- Záťažové balancery a proxy servery: Overte, či všetky záťažové balancery alebo reverzné proxy servery vo vašej infraštruktúre správne spracovávajú pre-flight požiadavky a prenášajú hlavičky CORS.
- Podpora viacerých jazykov: Zvážte, ako CORS interaguje s vašou stratégiou internacionalizácie (i18n) a lokalizácie (l10n) aplikácie. Uistite sa, že pravidlá CORS sú konzistentné v rôznych jazykových verziách vašej aplikácie.
Testovanie a ladenie CORS
Efektívne testovanie a ladenie CORS je životne dôležité. Tu sú niektoré techniky:
- Nástroje pre vývojárov prehliadača: Konzola pre vývojárov prehliadača je vašou prvou zastávkou. Karta „Sieť“ zobrazí pre-flight požiadavky a odpovede, pričom odhalí, či sú hlavičky CORS prítomné a správne nakonfigurované.
- Nástroj príkazového riadka `curl`: Použite `curl -v -X OPTIONS
` na manuálne odosielanie pre-flight požiadaviek a kontrolu hlavičiek odpovede servera. - Online kontroléry CORS: Početné online nástroje vám môžu pomôcť overiť konfiguráciu CORS. Stačí vyhľadať „CORS checker“.
- Unit a integračné testy: Napíšte automatizované testy na overenie, či vaša konfigurácia CORS funguje podľa očakávania. Tieto testy by mali pokrývať úspešné požiadavky medzi rôznymi pôvodmi aj scenáre, kde by CORS mal zablokovať prístup.
- Protokolovanie a monitorovanie: Implementujte protokolovanie na sledovanie udalostí súvisiacich s CORS, ako sú pre-flight požiadavky a blokované požiadavky. Monitorujte svoje protokoly na podozrivú aktivitu alebo chyby konfigurácie.
Záver
Zdieľanie zdrojov medzi rôznymi doménami (CORS) je dôležitý bezpečnostný mechanizmus, ktorý umožňuje kontrolovaný prístup k webovým zdrojom medzi rôznymi pôvodmi. Pochopenie toho, ako CORS funguje, najmä pre-flight požiadavky, je rozhodujúce pre vytváranie bezpečných a spoľahlivých webových aplikácií. Dodržiavaním osvedčených postupov uvedených v tejto príručke môžete efektívne riešiť problémy CORS a chrániť svoju aplikáciu pred potenciálnymi zraniteľnosťami. Nezabudnite vždy uprednostňovať bezpečnosť a starostlivo zvážiť dôsledky vašej konfigurácie CORS.
Ako sa vývoj webu vyvíja, CORS bude naďalej kritickým aspektom webovej bezpečnosti. Zostať informovaný o najnovších osvedčených postupoch a technikách CORS je nevyhnutné pre vytváranie bezpečných a globálne prístupných webových aplikácií.