Problem z polityką CORS – API blokowane

Spis treści

Wprowadzenie – Czym jest CORS i dlaczego blokuje API w WordPress

CORS (Cross-Origin Resource Sharing) określa, kiedy przeglądarka może udostępnić skryptowi odpowiedź z innego origin. Origin tworzą schemat, host i port, dlatego nawet dwa porty localhost są różnymi origin. Niektóre żądania poprzedza zapytanie sprawdzające OPTIONS, nazywane preflight.

Problem może pojawić się przy integracji z zewnętrznym API lub w aplikacji headless, której frontend i WordPress działają pod różnymi adresami. Nagłówki musi zwrócić serwer obsługujący API, nie sama strona wysyłająca żądanie.

Poniżej znajdziesz sposób diagnozy, wskazówki konfiguracji oraz najważniejsze ograniczenia bezpieczeństwa.

Zrozumienie mechanizmu CORS – jak działa polityka współdzielenia zasobów

Przeglądarka wysyła nagłówek Origin, a serwer odpowiada nagłówkami określającymi dostęp. Przy niektórych metodach lub nagłówkach najpierw wysyłany jest preflight OPTIONS z informacją o planowanej metodzie i nagłówkach. Jeśli preflight nie przejdzie, przeglądarka nie wyśle właściwego żądania.

Kluczowe nagłówki CORS to:

  • Origin: origin strony wysyłającej żądanie.
  • Access-Control-Allow-Origin: jeden dozwolony origin albo * dla odpowiednio publicznych zasobów.
  • Access-Control-Allow-Methods i Access-Control-Allow-Headers: metody i nagłówki dozwolone w odpowiedzi na preflight.
  • Access-Control-Allow-Credentials: zgoda na udostępnienie odpowiedzi przy żądaniu z danymi uwierzytelniającymi.
  • Access-Control-Max-Age: czas przechowywania wyniku preflight, ograniczany również przez przeglądarkę.

CORS egzekwuje przeglądarka. Żądanie niewymagające preflight może dotrzeć do serwera i zmienić dane, nawet jeśli przeglądarka następnie zablokuje odczyt odpowiedzi. CORS nie jest więc autoryzacją ani ochroną przed CSRF.

Diagnoza problemu – identyfikacja błędów CORS w konsoli

Błędy CORS są łatwe do zidentyfikowania dzięki charakterystycznym komunikatom w konsoli deweloperskiej przeglądarki. Najczęstsze komunikaty to:

  • No 'Access-Control-Allow-Origin' header is present on the requested resource – serwer nie zwrócił nagłówka pozwalającego na dostęp z domeny źródłowej
  • Response to preflight request doesn't pass access control check – zapytanie preflight (OPTIONS) zostało odrzucone
  • Multiple CORS header 'Access-Control-Allow-Origin' not allowed – nagłówek został zwrócony więcej niż raz.

Aby zdiagnozować problem CORS, otwórz narzędzia deweloperskie w przeglądarce (F12), przejdź do zakładki Console i Network. W zakładce Network szukaj zapytań oznaczonych na czerwono, a w Console poszukaj komunikatów zawierających słowo "CORS".

Sprawdź osobno OPTIONS i właściwe żądanie: adres po przekierowaniach, kod odpowiedzi, Origin oraz nagłówki Access-Control-Allow-*. Błąd 401, 403 lub 500, przekierowanie, problem TLS albo blokada WAF mogą ukrywać właściwą przyczynę pod komunikatem CORS. Porównaj nagłówki dla odpowiedzi poprawnej i błędu.

Konfiguracja nagłówków CORS – modyfikacja .htaccess

Najpierw ustal, która warstwa obsługuje API i dodaje nagłówki: WordPress, Apache, Nginx, proxy lub CDN. Nie konfiguruj tej samej polityki niezależnie w kilku miejscach. Plik .htaccess działa tylko z Apache, gdy odpowiednie dyrektywy są dozwolone; sam Nginx go nie odczytuje.

Przykład poniżej pokazuje wyłącznie nagłówek dla jednego zaufanego origin. Nie jest kompletną konfiguracją preflight ani uwierzytelniania. Nie dodawaj go do całej witryny bez oceny zakresu zasobów i istniejących nagłówków:

<IfModule mod_headers.c>
  Header set Access-Control-Allow-Origin "https://frontend.example"
</IfModule>

Zastąp adres rzeczywistym origin frontendu, bez ścieżki i końcowego ukośnika. Dla preflight serwer musi poprawnie odpowiedzieć na OPTIONS oraz dopuścić potrzebne metody i nagłówki. Sprawdź także odpowiedzi błędów: zachowanie dyrektyw Apache zależy od konfiguracji. Przed zmianą zrób kopię konfiguracji i przetestuj ją w bezpiecznym środowisku.

Jeśli nagłówki REST API dodaje już WordPress, powyższy przykład może spowodować duplikaty. Dla Nginx lub zewnętrznego API zastosuj konfigurację właściwego serwera. Sama lista metod CORS nie ogranicza operacji klientów poza przeglądarką.

Rozwiązania na poziomie WordPress – wtyczki i functions.php

Politykę REST API można dostosować w WordPressie, ale najpierw sprawdź działanie istniejących filtrów i nagłówków. Zmiana musi uwzględniać również odpowiedzi OPTIONS i błędów.

functions.php motywu: kod jest związany z aktywnym motywem i może zniknąć po jego aktualizacji lub zmianie. Polityka API zwykle nie powinna od niego zależeć.

Wtyczka: rozwiązanie konfiguracyjne lub własna wtyczka może działać niezależnie od motywu. Przed wyborem sprawdź jej aktualność, zakres działania oraz zgodność z konfiguracją serwera.

Niezależnie od metody nie wystarczy dopisać kolejnego Access-Control-Allow-Origin: trzeba świadomie dostosować istniejącą obsługę REST API i sprawdzić końcową odpowiedź widoczną dla przeglądarki.

Jeśli interesuje Cię szersze spojrzenie na bezpieczeństwo API, polecam przeczytać artykuł: Jak wykonać pełną optymalizację REST API w WordPress, gdzie znajdziesz więcej szczegółów na temat zabezpieczania endpointów API.

Problemy z API REST WordPress – specyfika endpointów

Domyślna funkcja rest_send_cors_headers zwraca otrzymany Origin, metody i Access-Control-Allow-Credentials: true także dla żądań nieuwierzytelnionych. Nie sprawdza przy tym listy zaufanych origin. Przed udostępnieniem prywatnego API oceń to zachowanie oraz wszystkie mechanizmy uwierzytelniania używane w projekcie.

Preflight nie zawiera cookies właściwego żądania. Nie wymagaj więc zalogowanej sesji dla samego OPTIONS; właściwe żądanie musi nadal przejść uwierzytelnienie i sprawdzenie uprawnień. Skuteczny preflight nie oznacza, że dostęp do danych jest dozwolony.

Niestandardowe endpointy zarejestrowane w REST API również korzystają z jego obsługi odpowiedzi; nie zakładaj, że wymagają osobnych nagłówków. Każdy endpoint musi mieć właściwy permission_callback i walidować dane niezależnie od CORS.

Przy uwierzytelnianiu przez cookies WordPress używa nonce REST API, zwykle w nagłówku X-WP-Nonce. Nonce pomaga chronić przed CSRF, ale nie zastępuje sprawdzania uprawnień. W integracji cross-origin przetestuj też sposób bezpiecznego przekazania nonce i dostępność cookies.

Bezpieczeństwo a CORS – jak nie otwierać luk w zabezpieczeniach

Dla prywatnych odpowiedzi dopuszczaj wyłącznie zaufane origin. Nie odbijaj bezwarunkowo wartości Origin i nie traktuj jej jako dowodu tożsamości klienta: klienci poza przeglądarką mogą ją dowolnie ustawić.

Access-Control-Allow-Origin: * może służyć publicznym zasobom, ale nie działa z trybem credentials: 'include'. Przy takim trybie potrzebne są dokładny origin i Access-Control-Allow-Credentials: true; ciasteczka mogą być dodatkowo ograniczone przez SameSite lub politykę przeglądarki.

Inne zagrożenia związane z nieprawidłową konfiguracją CORS to:

  • Wyciek danych: zaufanie do obcego origin w połączeniu z działającym uwierzytelnianiem może umożliwić obcej stronie odczyt prywatnej odpowiedzi.
  • CSRF: ograniczenie odczytu odpowiedzi nie uniemożliwia wysłania każdego żądania. Stosuj ochronę CSRF odpowiednią do sposobu uwierzytelniania.
  • Cache: przy odpowiedzi zależnej od Origin stosuj Vary: Origin; prywatne dane wymagają także odpowiednich zasad cache.

Ogranicz origin, metody i nagłówki do potrzebnych, a dostęp do operacji egzekwuj na serwerze przez uwierzytelnianie, autoryzację i walidację.

Testowanie rozwiązań – narzędzia do weryfikacji konfiguracji

Po wdrożeniu zmian w konfiguracji CORS ważne jest dokładne przetestowanie rozwiązania. Istnieje kilka narzędzi i metod, które mogą w tym pomóc:

Narzędzia deweloperskie przeglądarki: Zakładka Network pozwala na szczegółową analizę nagłówków HTTP. Sprawdź, czy zapytania zawierają nagłówek Origin, a odpowiedzi odpowiednie nagłówki Access-Control-Allow-*.

curl: pozwala sprawdzić odpowiedź serwera, ale nie egzekwuje CORS ani nie potwierdza działania w przeglądarce. Przykładowy preflight wykonaj na własnym, bezpiecznym endpointzie testowym obsługującym POST, zastępując oba adresy i dostosowując nagłówki do integracji:

curl -i -X OPTIONS 'https://api.example/wp-json/twoja-przestrzen/v1/zasob' \
  -H 'Origin: https://frontend.example' \
  -H 'Access-Control-Request-Method: POST' \
  -H 'Access-Control-Request-Headers: content-type, x-wp-nonce'

Sprawdź kod 2xx oraz zgodność origin, metody i nagłówków z odpowiedzią. Następnie powtórz test z niedozwolonym origin: odpowiedź nie powinna zezwalać na jego odczyt. W przeglądarce sprawdź także właściwe żądanie, błędy i dostęp z cookies, jeśli aplikacja ich używa. Nie przekazuj tokenów ani prywatnych danych zewnętrznym testerom.

Wiele domen i środowisk

Dla kilku frontendów porównuj pełny Origin z dokładną listą dozwolonych wartości. W odpowiedzi zwracaj tylko jeden pasujący origin, nigdy listę oddzieloną przecinkami. Nie zezwalaj automatycznie na wszystkie subdomeny ani na Origin: null.

Rozdziel konfigurację produkcyjną i testową. Jeśli odpowiedź zmienia się zależnie od Origin, użyj Vary: Origin i sprawdź, czy CDN oraz proxy respektują ten nagłówek również dla odpowiedzi bez dopasowania.

Strona HTTPS odwołująca się do API przez HTTP może zostać zablokowana z powodu mixed content, niezależnie od CORS. Sprawdź też poprawność certyfikatów i przekierowań.

W środowisku lokalnym uwzględnij dokładny schemat i port, np. http://localhost:3000. Nie dodawaj lokalnych adresów do produkcyjnej listy bez uzasadnienia i oceny ryzyka.

Podsumowanie – Najlepsze praktyki zarządzania polityką CORS

Przed wdrożeniem i po każdej zmianie sprawdź następujące kwestie:

Checklista optymalnej konfiguracji CORS:

Podstawowe ustawienia:

  • Określ zaufane origin i sprawdź, która warstwa wysyła nagłówki.
  • Ogranicz metody i nagłówki preflight do niezbędnych.
  • Ustal czas cache preflight odpowiedni dla zmian polityki.

Bezpieczeństwo:

  • Nie odbijaj dowolnego Origin i nie stosuj gwiazdki do prywatnych odpowiedzi.
  • Egzekwuj uwierzytelnianie, uprawnienia i ochronę przed CSRF niezależnie od CORS.
  • Sprawdź Vary: Origin i zasady przechowywania prywatnych odpowiedzi.

Testowanie:

  • Testuj dozwolony i niedozwolony origin, preflight oraz właściwe żądanie.
  • Sprawdź odpowiedzi błędów, przekierowania i działanie w przeglądarce.

Szczegóły mechanizmu i ograniczeń przeglądarek opisuje dokumentacja CORS w MDN.

Najczęstsze pytania o CORS

Jakie są różnice między CORS a JSONP?

CORS pozwala serwerowi określić dostęp przeglądarki do odpowiedzi z innego origin. JSONP to starsza technika oparta na ładowaniu skryptu, ograniczona do GET i wymagająca zaufania do wykonywanego kodu. W nowych integracjach stosuj CORS.

Czy CORS wpływa na wydajność strony?

Niektóre żądania wymagają dodatkowego zapytania OPTIONS, co zwiększa opóźnienie. Access-Control-Max-Age pozwala przeglądarce przez pewien czas przechowywać wynik preflight; przeglądarki mogą ograniczać ten czas.

Jak skonfigurować CORS dla wielu domen?

Porównuj pełny Origin z dokładną listą zaufanych adresów i dla pasującego zwracaj jeden Access-Control-Allow-Origin. Dodaj Vary: Origin i zadbaj o poprawną konfigurację cache. Nie odbijaj dowolnego Origin.

Czy CORS działa z WebSocket?

Nie, WebSocket nie korzysta z mechanizmu CORS. Serwer WebSocket powinien osobno sprawdzać Origin oraz uwierzytelnienie i uprawnienia połączenia.

Jak testować CORS lokalnie podczas rozwoju?

Różne porty localhost to różne origin. Skonfiguruj odpowiednie nagłówki w środowisku testowym i sprawdź wynik w przeglądarce. Postman i curl pomagają zbadać odpowiedź, ale nie egzekwują CORS.

Czym jest polityka CORS i dlaczego blokuje moje API w WordPress?

CORS określa, kiedy przeglądarka udostępnia skryptowi odpowiedź z innego origin. Niezgodne nagłówki blokują jej odczyt, a nieudany preflight może zatrzymać właściwe żądanie. CORS nie zastępuje ochrony przed CSRF.

Jak skonfigurować nagłówki CORS w WordPress?

Nagłówki można konfigurować na właściwej warstwie serwera lub w WordPressie. Najpierw sprawdź istniejące nagłówki REST API, proxy i wtyczek, aby uniknąć konfliktów i duplikatów.

Czy używanie Access-Control-Allow-Origin: * jest bezpieczne?

Gwiazdka może być właściwa dla świadomie publicznego zasobu bez danych użytkownika. Nie działa z trybem credentials: include i nie zastępuje autoryzacji ani ochrony przed CSRF. Dla danych prywatnych stosuj dokładną listę zaufanych origin.

Jak diagnozować problemy z CORS w przeglądarce?

Otwórz narzędzia deweloperskie (F12), przejdź do zakładki Console i szukaj komunikatów zawierających "CORS". W zakładce Network sprawdź nagłówki odpowiedzi pod kątem obecności Access-Control-Allow-*. Najczęstszy błąd to "No Access-Control-Allow-Origin header is present".

Czy WordPress REST API domyślnie obsługuje CORS?

WordPress domyślnie wysyła nagłówki CORS w REST API także dla żądań nieuwierzytelnionych. Funkcja rest_send_cors_headers zwraca otrzymany Origin oraz Allow-Credentials: true; nie jest to lista zaufanych origin. Dostęp do danych nadal zależy od uwierzytelniania i uprawnień endpointu.

Jakie są najczęstsze błędy konfiguracji CORS?

Częste problemy to odbijanie dowolnego Origin, brak obsługi preflight OPTIONS, zduplikowane nagłówki oraz błędna konfiguracja cache. Sprawdzaj również odpowiedzi błędów i różnice między środowiskami.

Masz problemy z konfiguracją CORS w WordPress? Chętnie pomożemy Ci wdrożyć poprawną politykę CORS, która zapewni zarówno funkcjonalność, jak i bezpieczeństwo Twojej aplikacji. Skontaktuj się z nami, aby uzyskać profesjonalne wsparcie w konfiguracji.