Broken Access Control (nieprawidłowa kontrola dostępu) zajmuje pozycję A01:2021 w zestawieniu OWASP Top 10 — jest to zagrożenie numer jeden dla aplikacji webowych. W 2017 roku było na piątym miejscu; awans wynika z jego powszechności i wysokiego wpływu: OWASP stwierdził, że 94% testowanych aplikacji zawierało jakąś formę tej podatności, a kategoria ta odpowiada za więcej wystąpień Common Weakness Enumeration (CWE) niż jakakolwiek inna. Kontrola dostępu zaczyna się tam, gdzie kończy się uwierzytelnianie: uwierzytelnianie potwierdza, kim jesteś; kontrola dostępu decyduje, co wolno ci zrobić. Gdy tych decyzji brakuje, są niepełne lub egzekwowane wyłącznie w przeglądarce, atakujący może odczytać lub zmodyfikować dane i funkcje, które powinny być niedostępne.
Co faktycznie egzekwuje kontrola dostępu
Poprawny model kontroli dostępu odpowiada przy każdym żądaniu na proste pytanie: czy ten konkretny podmiot ma prawo wykonać tę akcję na tym konkretnym obiekcie? Awarie występują, gdy odpowiedź jest zakładana, a nie sprawdzana. Dwa klasyczne kierunki eskalacji to eskalacja pozioma i pionowa.
- Eskalacja pozioma — użytkownik uzyskuje dostęp do zasobów należących do innego użytkownika na tym samym poziomie uprawnień. Przykład: użytkownik A otwiera
/api/orders/1043, zmienia ID na1044i odczytuje zamówienie użytkownika B. Ta sama rola, inny właściciel. - Eskalacja pionowa — użytkownik zdobywa uprawnienia wyższego poziomu. Przykład: zwykły użytkownik wywołuje
POST /api/admin/users, aby tworzyć konta, lub podmienia ukryte polerole=admin. Zupełnie inna rola.
Najczęstsze wzorce podatności
IDOR / BOLA (Insecure Direct Object Reference / Broken Object Level Authorization). To sztandarowy błąd eskalacji poziomej, a jako BOLA zajmuje pozycję API1:2023 w OWASP API Security Top 10. Aplikacja udostępnia bezpośrednie odwołanie do obiektu — identyfikator bazodanowy, nazwę pliku, UUID — i ufa, że klient poda tylko odwołania, które do niego należą. Ponieważ serwer nigdy ponownie nie weryfikuje własności, manipulacja identyfikatorem zwraca cudze dane. Przewidywalne, sekwencyjne identyfikatory (?invoice=8801) czynią enumerację trywialną, ale uwaga: zastąpienie ich UUID-ami to zaciemnienie, a nie zabezpieczenie. Rozwiązaniem jest weryfikacja własności po stronie serwera, a nie nieodgadywalny identyfikator.
Brak autoryzacji na poziomie funkcji. Funkcje administracyjne lub uprzywilejowane są chronione jedynie przez nieukazywanie linku w interfejsie. Sam endpoint nie sprawdza roli. Atakujący, który zna lub odgadnie /admin/delete-user — często łatwo znajdywany w plikach JavaScript lub przez fuzzing — wywołuje go bezpośrednio. Odpowiada to CWE-285 (Improper Authorization) oraz CWE-862 (Missing Authorization).
Wymuszone przeglądanie (forced browsing). Atakujący żąda adresów URL, parametrów lub metod HTTP, które nie są nigdzie podlinkowane, lecz nadal są obsługiwane. Bezpośrednie żądanie /reports/2026/q1-confidential.pdf lub wysłanie PUT/DELETE do endpointu chroniącego tylko GET omija kontrole zakładające, że użytkownicy będą podążać jedynie za dostarczonymi linkami. Częstymi znaleziskami są endpointy metadanych, pliki kopii zapasowych i trasy debugowania.
Inne częste warianty: błędna konfiguracja CORS udostępniająca API niezaufanym źródłom; tokeny JWT, których deklaracje (jak role czy sub) są zaufane bez walidacji podpisu; oraz mass-assignment, gdzie treść żądania ustawia pola (isAdmin, accountBalance), których klient nigdy nie powinien kontrolować.
Rzeczywisty wpływ
Awarie kontroli dostępu nie są teoretyczne. Podatność USPS Informed Delivery z 2018 roku pozwalała dowolnemu zalogowanemu użytkownikowi odpytywać dane kont ~60 milionów użytkowników przez nieuwierzytelniony parametr API — podręcznikowy BOLA. Wyciek First American Financial z 2019 roku ujawnił 885 milionów rekordów hipotecznych przez sekwencyjne identyfikatory dokumentów niewymagające żadnego uwierzytelnienia. Według CVSS v3.1 takie problemy często osiągają 8,0+ (High) — na przykład zdalnie wykorzystywalny IDOR ujawniający poufne dane osiąga CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N = 6,5, rosnąc ku 8–9, gdy dostępna jest także integralność lub funkcje administracyjne.
Jak to testować
- Testowanie różnicowe dwóch kont. Utwórz dwóch użytkowników (i jednego administratora). Przechwyć żądanie z konta A, a następnie odtwórz je z ciasteczkiem/tokenem sesji konta B. Jeśli B otrzyma dane A, masz błąd dostępu poziomego. Narzędzia jak Autorize lub Auth Analyzer w Burp Suite automatyzują to porównanie.
- Manipulacja parametrami. Zwiększaj, zmniejszaj i fuzzuj każdy identyfikator obiektu — ID, UUID, nazwy plików, numery kont — w tym te w treści JSON i deklaracjach JWT.
- Sondowanie na poziomie funkcji. Wyliczaj endpointy administracyjne i uprzywilejowane z source map JS oraz przez brute-force katalogów, a potem wywołuj je z sesją o niskich uprawnieniach.
- Testowanie metod i wymuszonego przeglądania. Próbuj alternatywnych czasowników HTTP i bezpośrednio żądaj niepodlinkowanych zasobów. Dopasuj zakres do przypadków testowych OWASP WSTG-ATHZ (Authorization Testing).
Jak temu zapobiegać
- Domyślnie odmawiaj (deny by default). Każdy zasób jest prywatny, dopóki reguła nie przyzna wyraźnie dostępu. Endpointy publiczne to wyjątek, który dodajesz na białą listę, a nie domyślność, którą zapominasz zablokować.
- Egzekwuj zawsze po stronie serwera. Kontrole po stronie klienta to UX, nie bezpieczeństwo. Wiążąca decyzja musi zapadać na serwerze, przy każdym żądaniu, dla każdego obiektu.
- Sprawdzaj własność, nie tylko rolę. Potwierdź, że uwierzytelniony podmiot faktycznie jest właścicielem lub jest uprawniony do tego rekordu. Wyprowadzaj tożsamość użytkownika z sesji/tokenu — nigdy z parametru
user_idpodanego przez klienta. - Centralizuj logikę. Kieruj wszystkie decyzje przez jeden komponent autoryzacji lub middleware, zamiast rozsiewać doraźne sprawdzenia
if. Odpowiada to NIST SP 800-53 AC-3 (Access Enforcement) i zasadzie najmniejszych uprawnień (AC-6). - Używaj odwołań pośrednich i limituj tempo. Preferuj odwołania mapowane per-sesja, loguj awarie kontroli dostępu i alarmuj przy powtarzających się odmowach, aby wychwycić enumerację.
- Testuj w sposób ciągły. Dodaj automatyczne testy autoryzacji do CI, aby nowy endpoint nie mógł trafić na produkcję bez weryfikacji własności.
Kontrola dostępu to praca projektowa, a nie filtr doklejany na końcu. Modeluj role i własność obiektów jawnie, egzekwuj każdą decyzję po stronie serwera z zasadą deny-by-default i weryfikuj to testowaniem dwóch kont przy każdym wydaniu. Ta dyscyplina zamienia zagrożenie nr 1 z OWASP w nieistotne zdarzenie.