CORS: Zdieľanie zdrojov medzi doménami

CORS v kontexte webu: prečo existuje a čo rieši

CORS (Cross-Origin Resource Sharing) je mechanizmus HTTP, ktorý umožňuje bezpečné zdieľanie zdrojov medzi rozdielnymi pôvodmi (origins). Opiera sa o hlavičky v požiadavkách a odpovediach, ktoré prehliadač rešpektuje pri čítaní dát z inej domény, subdomény, portu alebo protokolu. CORS rozširuje tzv. Same-Origin Policy (SOP) tak, aby webové aplikácie mohli pristupovať k API a statickým zdrojom naprieč doménami bez straty bezpečnosti.

Origin a Same-Origin Policy: základné pojmy

  • Origin = kombinácia scheme://host:port (napr. https://app.example.com:443).
  • Same-Origin Policy bráni skriptom načítaným z jedného pôvodu čítať citlivé odpovede z iného pôvodu.
  • CORS umožní kontrolované prelomenie tejto bariéry cez deklaratívne hlavičky na strane servera.

Aktéri a zodpovednosti

  • Prehliadač vynucuje pravidlá CORS a v prípade porušenia zablokuje prístup k odpovedi (JS nedostane telo, konzola vypíše chybu).
  • Server cieľového zdroja rozhoduje, komu (ktorému pôvodu) a za akých podmienok dá prístup pomocou CORS hlavičiek.
  • CDN/Proxy môže meniť hlavičky, kešovať preflight odpovede a ovplyvniť chovanie (pozor na Vary).

Typy požiadaviek: jednoduché, preflight a credentialed

  • Jednoduché požiadavky (bez preflightu): metódy GET, HEAD, POST s bezpečnými simple hlavičkami (napr. Accept, Content-Type s hodnotami typu application/x-www-form-urlencoded, multipart/form-data alebo text/plain), bez vlastných neštandardných hlavičiek.
  • Preflight: prehliadač najprv vyšle OPTIONS s hlavičkami Origin, Access-Control-Request-Method a prípadne Access-Control-Request-Headers. Server musí odpovedať s povolením, inak hlavná požiadavka nebude vykonaná.
  • Credentialed (s povereniami): ak klient posiela cookies/HTTP auth/klientské certifikáty (fetch s credentials: "include"), server musí odpovedať Access-Control-Allow-Credentials: true a nesmie použiť Access-Control-Allow-Origin: *; musí uviesť konkrétny pôvod.

Kľúčové hlavičky CORS a ich význam

  • Origin: automaticky pridávaná klientom; identifikuje pôvod volajúceho.
  • Access-Control-Allow-Origin: odpoveď servera s povoleným pôvodom (konkrétny https://example.com alebo * pri ne-credentialed požiadavkách).
  • Access-Control-Allow-Methods: metódy povolené pri preflighte (GET, POST, PUT, DELETE, OPTIONS…).
  • Access-Control-Allow-Headers: ne-simple hlavičky povolené v hlavnej požiadavke (napr. Authorization, X-Requested-With).
  • Access-Control-Expose-Headers: zoznam hlavičiek, ktoré môžu byť čitateľné z JS (bez toho vidí iba safe list).
  • Access-Control-Allow-Credentials: true ak sú povolené cookies/credentials.
  • Access-Control-Max-Age: čas, počas ktorého môže prehliadač kešovať výsledok preflightu (redukcia latencie; prehliadače majú vlastné horné limity).
  • Vary: Origin: extrémne dôležité pri CDN – odpoveď sa má líšiť podľa Origin. Bez toho riskujete cache poisoning alebo únik hlavičiek.

Životný cyklus preflightu krok za krokom

  1. JS (napr. fetch) chce urobiť PUT s hlavičkou Authorization.
  2. Prehliadač vyšle OPTIONS na rovnakú URL s Origin a Access-Control-Request-* hlavičkami.
  3. Server odpovie napr. Access-Control-Allow-Origin: https://app.example.com, Access-Control-Allow-Methods: PUT, Access-Control-Allow-Headers: Authorization, Access-Control-Max-Age: 600.
  4. Prehliadač si výsledek preflightu dočasne zapamätá a vykoná hlavnú požiadavku.

Bežné topológie: SPA, API a CDN

  • SPA na doméne A volá API na doméne B: nastavte B tak, aby podľa whitelistu odrážal Access-Control-Allow-Origin iba pre známe pôvody a pridal Vary: Origin.
  • CDN pred API: nech CDN rešpektuje a forwarduje Origin na pôvodný server; kešujte bezpečne podľa Vary a zvážte kešovanie preflightov.
  • Statické assety (fonty, obrázky, video): ak sa používajú naprieč doménami (napr. fonty), pridajte Access-Control-Allow-Origin a správny Content-Type.

Konfigurácia: návrhové vzory bez bezpečnostných dier

  • Reflexia pôvodu s whitelistom: server si pozrie Origin, ak je v zozname, vráti Access-Control-Allow-Origin s danou hodnotou a doplní Vary: Origin. Nikdy nereflektujte akýkoľvek Origin bez kontroly.
  • Credentialed API: použite konkrétny Access-Control-Allow-Origin (nie *) a Access-Control-Allow-Credentials: true. Obmedzte Allow-Methods a Allow-Headers na minimum.
  • Minimalizácia preflightu: preferujte simple metódy a hlavičky; posielajte JSON ako text/plain iba vtedy, ak to bezpečnostná politika dovoľuje a viete, čo robíte. Častejšie je lepšie akceptovať preflight a správne ho kešovať.

Príklady hlavičiek pre API odpovede

Ne-credentialed, viac domén cez CDN: Access-Control-Allow-Origin: *, Access-Control-Expose-Headers: ETag, Link, Vary: Origin (ak neskôr prejdete na per-origin politiku).

Credentialed iba pre app: Access-Control-Allow-Origin: https://app.example.com, Access-Control-Allow-Credentials: true, Access-Control-Expose-Headers: X-RateLimit-Remaining, Vary: Origin.

Preflight odpoveď: Access-Control-Allow-Origin: https://app.example.com, Access-Control-Allow-Methods: GET, POST, Access-Control-Allow-Headers: Authorization, Content-Type, Access-Control-Max-Age: 600, Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers.

Redirecty, cache a CORS

  • Presmerovania môžu zhodiť CORS, ak medzičlánok odstráni hlavičky alebo zmení protokol/host/port. Ideálne odpovedajte priamo bez 302/301, najmä na preflight.
  • CDN cache: vždy uvažujte o Vary na Origin a potenciálne aj na Access-Control-Request-* pre preflight.
  • ETag a podmienené požiadavky (If-None-Match) fungujú s CORS, ale iba ak sa zachovajú CORS hlavičky aj pri 304.

Bezpečnostné súvislosti: CORS ≠ autentizácia

  • CORS je mechanizmus prehliadača; nenahrádza autentizáciu ani autorizáciu. Server musí stále validovať tokeny, session a ACL.
  • Nikdy nepovoľujte * spolu s Allow-Credentials: true. Prehliadače to blokujú; ide aj o bezpečnostný princíp.
  • Oddeľte CORS od politiky CSP, COOP/COEP/CORP – tieto súvisiace mechanizmy riešia iné vektory (izolácia, načítateľnosť, cross-origin embedding).

Vplyv na SEO, AIO/AEO a LLM optimalizáciu

  • Indexácia a rendering: Googlebot s Web Rendering Service síce vykonáva JS, no API volania cez CORS môžu zlyhať a spôsobiť neúplný obsah. Dôležité dáta pre SEO (napr. produktové texty, FAQ) radšej renderujte SSR/SSG a neviažte ich na runtime CORS volanie.
  • Structured Data: neťahajte JSON-LD cez cross-origin runtime fetch; vložte ho priamo do HTML.
  • AIO/AEO (odpovede asistentov): ak widgety (HowTo, FAQ, Product) závisia od cross-origin médií (obrázky, video), povoľte CORS na asset doméne, inak embed komponenty v SPA môžu zobraziť „broken“ stav.
  • Performance: preflight pridáva RTT; pri vysokom podiele CORS volaní narastá TTI a zhoršia sa Core Web Vitals. Zvážte zlučovanie API, HTTP/2/3, kešovanie preflightu a same-origin proxy.

Diagnostika a testovanie

  • DevTools → Network: filtrujte OPTIONS, skontrolujte prítomnosť správnych CORS hlavičiek na preflighte aj na hlavnej odpovedi.
  • curl: simulujte preflight napr. cez curl -i -X OPTIONS https://api.example.com/resource -H "Origin: https://app.example.com" -H "Access-Control-Request-Method: PUT" -H "Access-Control-Request-Headers: Authorization".
  • Logy servera/CDN: zapnite logovanie pre OPTIONS, sledujte cache hit/miss a Vary správanie.
  • Monitorovanie: merajte percento CORS chýb v JS (window error handler) a korelujte s konverziami.

Najčastejšie chyby a ich riešenia

  1. „No ‚Access-Control-Allow-Origin‘ header is present“ – server nevracia povolenie pre daný pôvod; pridajte správny Access-Control-Allow-Origin a Vary: Origin.
  2. „The value of the ‚Access-Control-Allow-Origin‘ header contains ‚*‘ when credentials flag is true“ – použite konkrétny pôvod namiesto * a ponechajte Allow-Credentials: true.
  3. Preflight blokovaný 301/302 – odpovedajte priamo alebo presmerujte iba hlavnú požiadavku; preflight by mal dostať definitívnu odpoveď s CORS hlavičkami.
  4. Chýbajúce hlavičky pri 304 – aj 304 musí obsahovať relevantné CORS hlavičky.
  5. CDN stripuje hlavičky – povoľte a forwardujte Origin a zachovajte CORS hlavičky na edge.
  6. Príliš široké Allow-Headers/Methods – zužujte zoznam na nevyhnutné hodnoty, znižujete útokový povrch.

Optimalizácia výkonu: ako znížiť CORS latenciu

  • Zoskupujte volania a preferujte GET pre čitateľné zdroje s agresívnym cache-control.
  • Pre preflight použite rozumné Access-Control-Max-Age a zvážte jeho kešovanie na CDNe.
  • Premiestnite API pod rovnaký pôvod (reverse proxy, /api na tej istej doméne), kde je to možné.
  • Minimalizujte custom hlavičky; Authorization je častý spúšťač preflightu – zvážte alternatívne modely (napr. cookie s SameSite podľa potreby a CSRF ochranou), ale vždy s ohľadom na bezpečnosť.

Špecifiká cookies a SameSite

  • Pre cross-site cookies býva potrebné SameSite=None; Secure. Inak prehliadač cookie nepošle, aj keď CORS povoľuje credentials.
  • Nezabudnite zosúladiť doménu cookie (Domain) s tým, ako ju chcete používať naprieč subdoménami.

Fonty, obrázky a médiá naprieč doménami

  • Web fonty vyžadujú správne CORS hlavičky na asset doméne (Access-Control-Allow-Origin), inak sa môžu zablokovať.
  • Pri <img> načítanie síce prebehne, ale čítanie pixelových dát z canvasu bez CORS vedie k taintnutému canvasu (ochrana súkromia).
  • Video a audio streamy môžu vyžadovať kompatibilné CORS aj pre Range požiadavky a správne MIME typy.

Integrácia do vývojového procesu

  • Infra ako kód: definujte CORS politiky v Nginx/Apache/CloudFront/S3 konfigurácii ako súčasť repozitára.
  • Testy: pridajte integračné testy, ktoré validujú prítomnosť správnych hlavičiek pre bežné aj preflight scenáre.
  • Observabilita: metriky pre OPTIONS traffic, error rate a preflight cache hit rate na CDNe.

Checklist pre bezpečné zavedenie CORS

  • Máte explicitný zoznam povolených pôvodov (aj wildcardy pre subdomény, ak ich skutočne potrebujete).
  • Všetky odpovede (200/4xx/5xx/304) obsahujú konzistentné CORS hlavičky.
  • Preflight odpovedá bez presmerovania a uvádza presne tie metódy/hlavičky, ktoré potrebujete.
  • Pri credentialed scenároch nepoužívate * a vraciate Vary: Origin.
  • CDN forwarduje Origin a rešpektuje Vary; preflight je rozumne kešovaný.
  • DevTools a automatizované testy nehlásia CORS chyby v kritických užívateľských tokoch.

Zhrnutie

CORS je nevyhnutná súčasť moderného webu, ktorá umožňuje bezpečné prepojenie SPA, API a assetov naprieč doménami. Správne nastavené hlavičky, rozumné kešovanie preflightu, disciplinovaná bezpečnostná politika a integrácia kontrol do CI/CD znižujú latenciu, chránia údaje a stabilizujú rendering – čo v konečnom dôsledku prospieva SEO, AIO/AEO aj celkovej použiteľnosti webu.

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *