CORS (Cross-Origin Resource Sharing) – dla wielu programistów to tylko kilka linijek w konfiguracji serwera. Dla biznesu to często niewidzialny mur, który odcina aplikację od klientów, partnerów i własnych zespołów. W tym artykule przyjrzymy się, jak zbyt restrykcyjne polityki CORS potrafią zniszczyć UX, zablokować integracje i wpłynąć na konwersję. A przede wszystkim – jak znaleźć złoty środek między bezpieczeństwem a funkcjonalnością.
Dlaczego CORS w ogóle istnieje?
Przeglądarki domyślnie blokują zapytania z innej domeny. To mechanizm bezpieczeństwa, który zapobiega atakom CSRF i wyciekom danych. CORS to zestaw nagłówków HTTP, które mówią przeglądarce: „Hej, ta inna domena może bezpiecznie korzystać z naszych zasobów”. Problem pojawia się, gdy administratorzy w obawie przed atakami ustawiają nadgorliwe reguły:
- Zezwalają tylko na jedną, konkretną domenę origin, ignorując potrzeby frontendowców czy partnerów.
- Blokują metody HTTP inne niż GET/POST, uniemożliwiając bardziej złożone operacje.
- Nie obsługują preflightowych zapytań OPTIONS, co powoduje błędy 403.
Niestety, wiele firm wpada w pułapkę paranoi. Zamiast analizować realne zagrożenia, stosują politykę „zero zaufania”, która w praktyce oznacza „zero współpracy”.
Konsekwencje dla firm: realne przypadki
Przypadek 1: Aplikacja kliencka w React nie może połączyć się z backendem
Młody startup e-commerce rozbudował swój frontend o nowoczesny dashboard dla partnerów. Deweloperzy napisali elegancką aplikację w React, która miała komunikować się z REST API. Niestety, po wdrożeniu okazało się, że każdy endpoint zwraca błąd CORS. Powód? Backend zezwalał tylko na origin z https://sklep.pl, podczas gdy dashboard działał na https://dashboard.sklep.pl. Efekt: dni stracone na debugowanie, frustracja deweloperów i opóźniony launch dla partnerów.
Przypadek 2: Blokowanie własnych skryptów marketingowych
Firma wdrożyła narzędzie do analytics, które zbiera dane z różnych subdomen. Okazało się, że skrypt śledzący jest blokowany przez CORS, bo nie ma odpowiednich nagłówków Access-Control-Allow-Origin. Analityka pokazywała zaniżone wyniki, a działy marketinu podejmowały decyzje na podstawie niepełnych danych. Nikt nie sprawdził konfiguracji CORS – wszyscy myśleli, że to błąd narzędzia.
Przypadek 3: Integracja z API partnera nie działa
Firma B2B potrzebowała wymieniać dane z platformą klienta poprzez REST API. Klient miał rygorystyczną politykę CORS zezwalającą tylko na origin z https://panel.klienta.com. Tymczasem nasza aplikacja działała na https://app.naszafirma.pl. Deweloperzy spędzili tydzień na pisaniu proxy, które obchodziło CORS, zamiast poprosić klienta o zmianę konfiguracji. Ostatecznie integracja działała, ale z opóźnieniem i dodatkowymi kosztami.
Jak znaleźć złoty środek?
Kluczowe jest podejście oparte na zasadzie least privilege, ale z myślą o przyszłości. Oto kilka praktycznych reguł:
- Używaj Allow-Origin z listą dozwolonych domen, a nie gwiazdką. Ale lista powinna być dynamiczna – łatwo rozszerzalna bez zmiany kodu. Rozważ przechowywanie dozwolonych originów w zmiennych środowiskowych lub bazie danych.
- Sprawdzaj, czy potrzebujesz preflight. Jeśli twoje API ma endpointy, które nie generują skutków ubocznych (np. tylko GET), możesz użyć prostych zapytań i uniknąć preflighty. To zmniejsza narzut.
- Testuj konfigurację pod kątem rzeczywistych przypadków użycia. Stwórz zestaw testów automatycznych, które symulują zapytania z różnych domen i metod. Użyj narzędzi takich jak
curlz odpowiednimi nagłówkami Origin. - Dokumentuj politykę CORS. Niech każdy deweloper wie, co jest dozwolone i dlaczego. Unikaj sytuacji, w której to jeden admin ma wiedzę.
- Rozważ użycie proxy w developmencie. Pozwól frontendowcom na pracę lokalną bez bólów głowy, ale utrzymuj restrykcje na produkcji.
Pułapki, na które warto uważać
- Zapominanie o nagłówkach Vary. Jeśli używasz dynamicznego Allow-Origin, pamiętaj o wysłaniu
Vary: Origin. Inaczej przeglądarki mogą cache’ować odpowiedzi i serwować je z błędnym originem. - Nadmierna ilość dozwolonych metod. Jeśli nie potrzebujesz DELETE, nie włączaj go. Ale jeśli twoja aplikacja używa RESTu, to PUT i DELETE są standardem.
- Brak obsługi OPTIONS. Serwer musi odpowiadać na preflight poprawnymi nagłówkami, w tym Access-Control-Allow-Methods i Access-Control-Allow-Headers.
- Zapominanie o nagłówkach cache dla preflighty. Preflight można cache’ować na kilka minut, aby zmniejszyć narzut.
Podsumowanie
CORS to nie tylko zabezpieczenie – to element UX i architektury integracji. Zbyt restrykcyjna polityka odcina firmę od partnerów, spowalnia rozwój i generuje koszty. Zbyt liberalna naraża na ataki. Klucz to zrozumienie własnego ekosystemu: skąd pochodzą zapytania, jakie metody są potrzebne, które nagłówki muszą być przesyłane. Regularny audyt konfiguracji i testy automatyczne pomogą utrzymać balans.
Pamiętaj: CORS nie musi być wrogiem. Może być sprzymierzeńcem, jeśli go dobrze skonfigurujesz. A jeśli potrzebujesz pomocy przy audycie bezpieczeństwa swojego API – w JurskiTech chętnie spojrzymy na to świeżym okiem.


