---
robots: noindex, nofollow
lang: en
slideOptions:
transition: fade
---
# Szkolenie z OWASP TOP 10 2025
<img src="https://sekurak-prod.eu-central-1.linodeobjects.com/img/Kamil%20Jarosin%CC%81ski-10aeeedaa408f799..JPG" alt="Kamil Jarosiński" height="450" width="450" style="border-radius: 50%; object-fit: cover; object-position: 50% 15%;"/>
__Kamil Jarosiński__
- Pracuję w [Securitum](https://securitum.pl)
- Mam ponad siedem lat (2018+) doświadczenia w pentestach w Securitum
- Zajmuje się głównie pentestami aplikacji webowych, API, Cloud, IoT, mobilki oraz [Szkoleniami](https://securitum.pl/szkolenia/)
- Prelegent na konferencji: Mega SHP (2019, 2021, 2025) i Cyberstarter.
- Współautor książki [Wprowadzenie do bezpieczeństwa IT tom II](https://wdbit2.sekurak.pl/)
---
**Organizacyjnie**
- Plan: 09:00-17:00.
- 10 minut przerwy co ~60 minut.
- Przerwa obiadowa: 12:30-13:15.
- Pytania zadawajcie na bieżąco.
---
**Agenda**
1. Wprowadzenie czym ogólnie jest OWASP TOP 10 i jak można go używać.
2. Omówienie wszystkich punktów standardu.
3. Punkty będziemy poznawać na dużej liczbie praktycznych przykładów. :smile:
---
# OWASP TOP 10 - czym jest

[OWASP TOP 10 2025 RC](https://owasp.org/Top10/2025/) - to standard opisujący 10 najistotniejszych ryzyk bezpieczeństwa grożących aplikacjom webowym.
Aktualizowany jest co kilka lat, na bazie informacji zbieranych od firm zajmujących się testowaniem bezpieczeństwa aplikacji www, jak również obserwacji dotyczących zmieniającego się krajobrazu podatności.
Najnowsza wersja została wydana w listopadzie 2025.

---
## Jak używać OWASP TOP 10?
Sam OWASP opisuje Top 10 jako dokument [głównie służący podniesieniu świadomości](https://owasp.org/Top10/A00_2021_How_to_use_the_OWASP_Top_10_as_a_standard/).
W rzeczywistości bywa jednak używany bardziej formalnie w procesie rozwijania aplikacji webowych. Poniżej kilka przykładów.
### ... jako punkt referencyjny do błędów bezpieczeństwa
Część klientów Securitum oczekuje, że w raportach z testów bezpieczeństwa aplikacji webowych znajdzie się informacja, którego punktu z OWASP TOP 10 dana podatność dotyczy. Dzięki temu łatwiej znaleźć np. dodatkowe opisy czy sugestie naprawy tego błędu w zależności od technologii.
Analogicznie, niektóre frameworki webowe zawierają opisy (oficjalne lub nieoficjalne), jakie podejście jest w nich stosowane, by zabezpieczyć się przed ryzykami opisanymi w standardzie. [Np. Django](https://github.com/boomcamp/django-security, https://docs.djangoproject.com/en/6.0/topics/security/).
Podobnież, niektóre narzędzia do szukania błędów bezpieczeństwa również klasyfikują błędy w odniesieniu do OWASP TOP 10. [Np. Sonarqube](https://www.sonarqube.org/features/security/owasp/).
### ... jako punkt startowy do wdrażania procesów i mechanizmów bezpieczeństwa w aplikacji webowej
Standard OWASP TOP 10 siłą rzeczy jest ograniczony - pokrywa bowiem tylko dziesięć najpoważniejszych ryzyk. Jeżeli jednak pracujemy nad aplikacją webową, w której nie było do tej pory ustandaryzowanego procesu jeśli chodzi o jej bezpieczeństwo, to Top 10 może być dobrym punktem startowym.
**Przykładowa implementacja:**
Przygotować techniczną rozpiskę wszystkich punktów z OWASP TOP 10 pod następującym kątem:
1. Jakie mechanizmy bezpieczeństwa (programistyczne, architekturalne, infrastrukturalne itp.) stosujemy, by przed danym ryzykiem się zabezpieczyć lub je zminimalizować.
2. Jeśli jakieś ryzyko naszej aplikacji nie dotyczy - warto zdefiniować dlaczego i czy może się to zmienić.
3. Jak często weryfikujemy, czy nie występują błędy wynikające z punktów OWASP TOP 10.
4. W jaki sposób można zweryfikować, czy dany punkt jest spełniony.
Tego typu dokument powinien być dostępny dla wszystkich osób pracujących nad daną aplikacją i przekazywany również nowym osobom dołączającym do zespołu później.
### ... jako inspiracja do testów bezpieczeństwa
OWASP TOP 10 może być pomocne osobom testującym bezpieczeństwo danej aplikacji jako inspiracja, tj. lista punktów, które należy w aplikacji zweryfikować (jeśli się tego jeszcze wcześniej nie zrobiło).
W każdym z punktów OWASP TOP 10 znajduje się opis kilku przykładowych ataków wynikających z danego ryzyka, jak również zewnętrznych referencji, pomagających lepiej zrozumieć jak testować dany punkt.
### ... jako checklista/certyfikat
Niekiedy klienci mogą wymagać potwierdzenia, że aplikacja jest bezpieczna (np. przed przekazaniem do niej danych osobowych swoich pracowników). Jeżeli klient nie ma konkretniejszych wymagań względem jakiego standardu aplikacja powinna zostać przetestowana (np. PCI DSS), wówczas potwierdzenie "zgodności z OWASP TOP 10" może zostać przyjęte, jako że jest to standard o bardzo dużej rozpoznawalności na rynku.
Warto jednak podkreślić, że nie istnieją żadne oficjalne certyfikacje na zgodność z OWASP TOP 10. Dokumentami, które warto przygotować to dokument pokazujący praktyki stosowane by zabezpieczać się przed ryzykami z OWASP TOP 10 i/lub wyniki testów bezpieczeństwa potwierdzające, że nie znaleziono błędów bezpieczeństwa pokrywających tematy z OWASP TOP 10. OWASP **nie pochwala** zapewnień twórców tego typu oprogramowania, że są one "w pełni zgodne z OWASP TOP 10".
> Tools cannot comprehensively detect, test, or protect against the OWASP Top 10 due to the nature of several of the OWASP Top 10 risks, with reference to A04:2021-Insecure Design. **OWASP discourages any claims of full coverage of the OWASP Top 10, because it’s simply untrue.**
[Źródło](https://owasp.org/Top10/A00_2021_How_to_use_the_OWASP_Top_10_as_a_standard/)
# Jak czytać OWASP TOP 10?
Każdy punkt w OWASP TOP 10 składa się z kilku części:
1. Ogólny opis ryzyka, zazwyczaj opisujący przykładowe ataki.
2. Metody zabezpieczenia przed ryzykiem.
3. Przykładowe scenariusze ataków - będące bardziej techniczne niż te przykładwy powyżej.
4. Referencje - zazwyczaj do innych źródeł OWASP-u, choć nie zawsze.
5. Lista CWEs - odniesienia do listy błędów z CWE (*Common Weakness Enumeration*), które składają się na dany punkt z OWASP TOP 10.
:::warning
:warning: Uwaga: prywatna opinia!
:::
Gdy sam analizowałem standard OWASP TOP 10, to w przypadku problemów ze zrozumieniem "co autor miał na myśli", zazwyczaj najbardziej pomagała mi lista CWE.
Lista CWE praktycznie w każdym przypadku zawiera ponad 20 opisów konkretnych błędów, które zazwyczaj dają lepszy ogląd czego dany punkt dotyczy.
# Cheat sheet series
Jak zabezpieczać się przed różnymi podatnościami:
https://cheatsheetseries.owasp.org/
# A01:2025 – Broken Access Control
https://owasp.org/Top10/2025/A01_2025-Broken_Access_Control/
Tzw. **błędy kontroli dostępu**. Punkt dotyczy wszelkiego rodzaju błędów, polegających na tym, że napastnik uzyskuje dostęp do zasobu/rekordu/usługi/komponentu/funkcjonalności, do którego/której nie powinien być uprawniony. Poprzez dostęp rozumiemy tutaj zarówno odczyt, jak i modyfikację/zapis czy usuwanie.
:::info
W ramach tej kategorii dodano w obecnej edycji podatność Server-Side Request Forgery (SSRF), co jest dość dziwne według mnie.
:::
## Dema
**Demo 1. IDOR - Insecure Direct Object Reference**
* <https://sekurak.pl/wielkopolskie-centrum-medycyny-pracy-zmieniajac-w-przegladarce-numer-id-mozna-bylo-zobaczyc-wyniki-badan-innych-pacjentow/>
* <https://sekurak.pl/oddawales-krew-twoje-zaswiadczenie-w-ikp-mialo-przewidywalny-identyfikator/>
Poprzez błąd w aplikacji uzyskujemy dostęp do faktury innego użytkownika.
https://portswigger.net/web-security/access-control/lab-insecure-direct-object-references
:::info
:information_source: Rozwiązaniem tego problemu jest zazwyczaj weryfikacja, czy dany zasób jest powiązany z kontem obecnie zalogowanego użytkownika.
Alternatywą (choć nie wykluczającą) jest zastosowanie losowych tokenów (np. w postaci UUID) zamiast rosnących liczb całkowitych jako identyfikatora zasobu.
Np. https://example.com/invoice?id=e21029fd-f759-41cc-8dde-2c7598ea43e6
:::
**Demo 2. "Ukryty" panel admina (forced browsing)**
W aplikacji jedyne zabezpieczenie panelu admina polega na schowanie go pod "niezgadywalnym" adresem URL. Ale przyjrzymy się źródłom JS tej aplikacji...
https://portswigger.net/web-security/access-control/lab-unprotected-admin-functionality-with-unpredictable-url
**Demo 3. Możliwość zmiany roli użytkownika.**
https://portswigger.net/web-security/access-control/lab-user-role-can-be-modified-in-user-profile
**Demo 4. Niepoprawna konfiguracja CORS**
https://portswigger.net/web-security/cors/lab-null-origin-whitelisted-attack
**Demo 5. Dostęp do metadanych via SSRF**
https://portswigger.net/web-security/xxe/lab-exploiting-xxe-to-perform-ssrf
# A02:2025 – Security Misconfiguration
https://owasp.org/Top10/2025/A02_2025-Security_Misconfiguration/
**Błędy konfiguracji** zarówno części serwerowej, jak i aplikacyjnej. Poniżej kilka typowych reprezentantów tej podantości:
1. Brak hardeningu usług sieciowych lub niewłaściwie ustawione uprawnienia w usługach chmurowych,
2. Włączenie niepotrzebnych funkcji (np. otwarcie niepotrzebnych portów, usług, stron, kont lub uprawnień),
3. Stosowanie kont o domyślnych nazwach użytkowników i hasłach,
4. Wyświetlanie stack trace’ów zawierających zbyt szczegółowe informacje o aplikacji lub środowisku,
5. Nieodpowiednia konfiguracja serwerów aplikacyjnych, frameworków (np. Struts, Spring, ASP.NET), bibliotek i baz danych,
6. Niewysyłanie tzw. nagłówków bezpieczeństwa.
## Dema
**Demo 1. Wyświetlanie dokładnej treści wyjątków**
1. Zróbmy Google Hacking w domenie gov.pl.
<https://www.exploit-db.com/google-hacking-database>
<https://gist.github.com/aw-junaid/cba1717689b9a1a942451b774085aa32>
`"mysql_fetch_array()" site:gov.pl`
2. https://beanstack.io - wydobycie wersji oprogramowania na bazie treści wyjątków.
3. Wykorzystanie tzw. ERROR-based SQL Injection (https://training.securitum.com/2/index.html) ```extractvalue('',concat('!',version()))```
**Demo 2. Ujawnianie wersji oprogramowania**
Znowu Google Hacking w gov.pl.
**Demo 3. XXE**
https://portswigger.net/web-security/xxe/lab-exploiting-xxe-to-retrieve-files
Zabezpieczenie to zazwyczaj zmiana konfiguracji parsera: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
**Demo 4. Flagi ciasteczek**
Zobaczmy, na czym polegają flagi ciasteczek: `HttpOnly`, `Secure` i `SameSite`.
* https://sekurak.pl/flaga-cookies-samesite-jak-dziala-i-przed-czym-zapewnia-ochrone/
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
* https://replit.com/@ja-sec/samesite
* https://372e9ce0-8c5c-4a4a-ae69-0397031b24b8-00-1y3qugmc6chgx.janeway.replit.dev:3003/set-cookie
## Checklista
* ✔️ Zweryfikuj, że serwer nie wyświetla zawartości katalogów
* ✔️ Zweryfikuj, że serwer nie wyświetla dokładnych wersji komponentów
* ✔️ Zweryfikuj, że aplikacja nie wyświetla dokładnych treści wyjątków
* ✔️ Zweryfikuj ustawienie tzw. [nagłówków bezpieczeństwa](https://securityheaders.com/) (https://sekurak.pl/jak-w-prosty-sposob-zwiekszyc-bezpieczenstwo-aplikacji-webowej/)
* ✔️ Zweryfikuj ustawienie parametrów `HttpOnly`, `Secure` i `SameSite` dla ciasteczek
* ✔️ Zweryfikuj, czy wyłączone jest przetwarzenie zewnętrznych encji lub DTD w parserze XML.
* ✔️ Zweryfikuj, czy usunięte/wyłączone są wszelkie domyślne hasła i dostępy do aplikacji
* ✔️ Zweryfikuj, czy aplikacja/framework/serwer nie ma funkcjonalności typu "demo", które należy wyłączyć.
* ✔️ Zweryfikuj w dokumentacji frameworków/bibliotek używanych przez aplikacje, czy istnieją pewne parametry bezpieczeństwa, które powinny być włączone przy wdrażaniu aplikacji na produkcję.
# A03:2025 – Software Supply Chain Failures
https://owasp.org/Top10/2025/A03_2025-Software_Supply_Chain_Failures/
**Brak monitorowania używanego oprogramowania**
Ten punkt to stały bywalec standardu OWASP TOP 10. Dotyczy wszelkiego rodzaju błędów bezpieczeństwa wynikających ze względu na brak monitorowania używanego oprogramowania co może prowadzić do użycia nieaktualnych, podatnych, zatrutych, złośliwych komponentów.
W obecnej wersji jest to punkt związany z używaniem niaktualnych, podatnych komponentów, który został rozszeżony o elementy zagrożeń związanych z Supply Chain.
Może dotyczyć wszelkiego rodzaju komponentów aplikacji:
* Zależności programistycznych,
* Systemu operacyjnego,
* Używanych bibliotek,
* Serwerów i usług (np. k8s, systemy kolejkowe, bazy danych itp.)
Najistotniejszym sposobem implementacji tego punktu jest wdrożenie rozwiązania, które pozwoli weryfikować wersje zależności na bieżąco oraz wdrożenie procesu aktualizacji zależności z zaufanych źródeł.
* <https://sekurak.pl/zaskakujaca-metoda-infekcji-wielkich-i-mniejszych-firm-wykonali-swoj-kod-w-systemach-apple-netflixa-shopify-ubera-paypala-microsoftu-konca-nie-widac/>
* <https://www.websecuritylens.org/how-dependency-confusion-attack-works-and-how-to-prevent-it/>
## Dema
**Demo 1. Wordpress plugin**
W przypadku używania podatnej wersji oprogramowania np. pluginu do Wordpress może doprowadzić do możliwości przeprowadzenia ataku.
**Demo 2. Snyk**

Poznajmy przykład narzędzia, które pozwala na weryfikację wersji zależności - [snyk](https://snyk.io) - (https://research.securitum.com/mutation-xss-via-mathml-mutation-dompurify-2-0-17-bypass/).
Oraz można wygenerować i przeskanować SBOM
```sh!
mkdir snyk
npm init
npm install dompurify@2.0.0 react-server-dom-webpack@19.2.0
snyk test
```
**Demo 3. Trivy**

Koljene narzędzia które działa podobnie jak snyk, czyli [trivy](https://trivy.dev/docs/latest/guide/scanner/misconfiguration/)
Poniżje przestawiono przykład dla pliku Dockerfile
```sh!
curl -O https://raw.githubusercontent.com/epi052/feroxbuster/refs/heads/main/Dockerfile
trivy config Dockerfile
```
Skan można przeprowadzić też dla zbudowanych obrazów
```sh!
docker build . -t feroxbuster:latest
trivy image feroxbuster:latest
```
Oraz można wygenerować i przeskanować SBOM
```sh!
npm init
npm install dompurify@2.0.0 react-server-dom-webpack@19.2.0
trivy fs . -f cyclonedx -o sbom.json
trivy sbom sbom.json
```
## Checklista
* ✔️ Zweryfikuj, czy zdefiniowano sposób weryfikacji, czy komponenty używane w rozwoju oprogramowania są aktualne CI/CD, IDE, zależności (tj. nie mają znanych błędów bezpieczeństwa),
* ✔️ Zweryfikuj, czy zdefiniowano proces wykonywania aktualizacji poszcególnych komponentów
* ✔️ Zweryfikuj, czy komponenty używane w aplikacji nie mają znanych problemów bezpieczeństwa
* ✔️ Zweryfikuj, czy istnieje Software Bill of Materials (SBOM)
* ✔️ Zweryfikuj, czy wszystkie zależności są faktycznie niezbędne
* ✔️ Pobieraj zależności tylko z oficialnych źródeł oraz preferuj konieczność podpisów cyfrowych
# A04:2025 – Cryptographic Failures
https://owasp.org/Top10/2025/A04_2025-Cryptographic_Failures/
W wolnym tłumaczeniu: **zaniedbania kryptograficzne**. Ten punkt pokrywa jakiekolwiek błędy związane ze złym użyciem kryptografii lub brakiem jej użycia. Zazwyczaj dotyczy następujących aspektów:
* Szyfrowania danych w wartswie transportu
* Szyfrowania danych "w spoczynku"
* Źródła losowości
* Zarządzanie kluczami
* Weryfikacja certyfikatów
* Sposób przechowywania haseł
## Linki
- https://ssl-config.mozilla.org/
- https://www.ssllabs.com/ssltest/
- https://tweetnacl.js.org/
## Dema
Zobaczmy kilka podstawowych operacji kryptograficznych i wynikających z tego dobrych praktyk:
* https://colab.research.google.com/drive/1WCsbqn4whsH4AgtLg6ODseLJexugllB7#scrollTo=VWdlDMghtlAp
* https://sekurak.pl/obliczanie-stanu-generatora-liczba-pseudolosowych-na-przykladzie-math-random-z-firefoksa/
* https://github.com/masalinas/coin-machine/blob/master/common/models/Bittrex.js
* https://sekurak.pl/zobacz-nasz-100-stronicowy-raport-z-audytu-bezpieczenstwa-aplikacji-protego-safe/
## Checklista
* ✔️ Zweryfikuj, czy komunikacja pomiędzy różnymi komponentami jest szyfrowana algorytmem TLS (obecnie zaleca się stosować co najmniej TLSv1.2). Ten punkt jest niezbędny, jeśli komunikacja odbywa się poprzez Internet, ale mocno zalecany również w środowisku LAN.
* ✔️ Zweryfikuj poprawność konfiguracji SSL za pomocą narzędzi do tego przeznaczonych (np. [Qualys SSL Labs](https://www.ssllabs.com/ssltest/)).
* ✔️ W przypadku użycia szyfrowania symetrycznego, zweryfikuj, czy używany jest AES-GCM lub ChaCha20,
* ✔️ W przypadku użycia szyfrowania asymetrycznego, zweryfikuj, czy używany jest RSA2048+ lub Poly1305.
* ✔️ Zweryfikuj, czy zawsze jest weryfikowana sygnatura danych zaszyfrowanych.
* ✔️ Zweryfikuj, czy do haszowania haseł używany jest algorytm bcrypt, scrypt lub argon2.
* ✔️ Zweryfikuj, czy do generacji liczb losowych lub losowych ciągów znaków używany jest CSPRNG (*Cryptographically Secure PseudoRandom Number Generator*) - dotyczy to również generacji IV/nonce dla celów szyfrowania symetrycznego.
* ✔️ Zweryfikuj, czy klucze kryptograficzne nie są przechowywane w kodach źródłowych aplikacji (powinno być wykorzystane rozwiązanie do zarządzania kluczami lub podmontowanie kluczy jako plików w K8S)
* ✔️ Zweryfikuj, czy procedury weryfikujące certyfikaty zawsze sprawdzają pełen łańcuch certyfikatów
# A05:2025 – Injection
https://owasp.org/Top10/2025/A05_2025-Injection/
Podatności klasy **injection** (tłumaczone na polski czasem jako **wstrzyknięcia**).
Najsłynniejszy przykład to SQL Injection, np. (https://dbfiddle.uk/5lrWvdd6)
```java
@GET
@Path("/search")
public Response getProducts(@QueryParam("query") query) {
/* (...) */
Database.execute(
"SELECT * " +
"FROM products " +
"WHERE productName LIKE '%" + query + "%'"
);
/* (...) */
}
```
Podatność w tym przypadku wynika ze sklejania zapytania SQL - i wykorzystaniu pochodzącego od użytkownika parametru `query` w zapytaniu.
W efekcie użytkownik może wkleić własną treść zapytania i wykonać dowolne zapytanie SQL.
---
Podatności klasy Injection może być jednak o wiele więcej:
* **OS Command Injection**
```
child_process.exec(`ffmpeg -i ${inputFilename}`)
```
* **LDAP Injection**
```
ldap_search("(&(cn=[$login])(userPassword=MD5[$pass]))")
```
* **XSS**
```
return "<div>" + username + "</div>"
```
* **XML Injection**
```
xml += "<username>" + username + "</username>"
```
* **Server-Side Template Injection**
```
Velocity.evalute(ctx, c, t, "Witaj " + name);
```
* **HQL Injection**
```
String query = "SELECT u FROM users u WHERE u.username = " + username
```
---
Cechą wspólną tych podatności jest to, że w każdej z nich używana jest konkatenacja lub interpolacja ciągów znaków.
Innymi słowy, gdy widzimy kod podobny do poniższego:
```
data = "user:" + username
// lub
data = "user:${username}"
```
Automatycznie powinna nam się zapalać lampka nad głową, że to może być niebezpieczne! :bulb:
---
Sposób radzenia sobie z tymi podatnościami zależy bardzo mocno od tego, w jakim konkretnym języku mamy wstrzyknięcie. Na przykład:
* Typową ochroną przed SQL Injection są [zapytania parametryzowane](https://cheatsheetseries.owasp.org/cheatsheets/Query_Parameterization_Cheat_Sheet.html)
* Typową ochroną przed podatnościami typu OS Command Injection jest wywoływanie nowych procesów przez funkcje, które przyjmują tablicę parametrów, zamiast jednego stringa, który traktowany jest jako kod.
* Ochroną przed XSS jest [enkodowanie danych w sposób odpowiedni do kontekstu lub użycie silników szablonów](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html).
* Dla innych podatności: warto poszukać w Google: `<system> injection prevention`
## Dema
**Demo 1. SQL Injection**
https://portswigger.net/web-security/sql-injection/examining-the-database/lab-listing-database-contents-non-oracle (https://dbfiddle.uk/)
:::danger
Zapytania parametryzowane nie działają w każdej cześci zapytania SQL, przykładowo w klauzuli `ORDER BY` zobaczmy do czego może to doprowadzić
:::
```!
/?search=ser
/?sort=(SELECT CASE WHEN (1=0) THEN name ELSE price END)
/?sort=(SELECT+case+when+('3'=substring(sqlite_version(),1,1))+then+name+else+price+end)
sqlmap -u 'http://<URL>/?sort=name' --flush-session
```
**Demo 2. XSS**
https://portswigger.net/web-security/cross-site-scripting/exploiting/lab-stealing-cookies (https://sekurak.pl/pelen-raport-z-realnych-testow-bezpieczenstwa-aplikacji-eventowej-bez-zadnej-cenzury/)
**Demo 3. Server-Side Template Injection**
https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-using-documentation
**Demo 4. Walidacja z użyciem blacklist**
Czasem zabezpieczenie przed podatnościami typu injection może polegać na zastosowaniu tzw. blacklist (czyli zdefiniowania wejścia, które uważamy za niebezpieczne i blokowanie go). Zobaczmy, dlaczego to nie jest dobre podejście.
https://jsbin.com/naxisubapu/edit?output
## Checklista
* ✔️ Zweryfikuj, czy wszystkie przyjmowane przez aplikacje dane od użytkownika są walidowane pod kątem poprawności typów i/lub formatu (np. czy sprawdzana jest poprawność daty, liczb itp.)
* ✔️ Zweryfikuj, czy do walidacji jest używane podejście opierające się o whitelisty (czyli zdefiniowanie jak wygląda poprawne wejście), a nie o blacklisty (czyli zdefiniowanie jak wygląda niepoprawne wejście i blokowanie go)
* ✔️ Zweryfikuj, czy wszelka walidacja odbywa się po stronie serwera
* ✔️ Zweryfikuj, czy używane są zapytania parametryzowane, systemy szablonów, ręczna weryfikacja danych lub inne sposoby ogólnie chroniące przed podatnościami typu Injection
* ✔️ Zweryfikuj, czy parametryzacja zapytań SQL jest użyta dla wszystkich parametrów (w szczególności do pól z sortowaniem danych)
* ✔️ Zweryfikuj, czy aplikacja w miarę możliwości unika interpolacji lub konkatenacji danych pochodzących od użytkownika przy użyciu ich do zapytań w innych systemach
# A06:2025 – Insecure Design
https://owasp.org/Top10/2025/A06_2025-Insecure_Design/
Błędy w **projekcie aplikacji**. Punkt dodany w wersji OWASP TOP 10 2021.
OWASP odróżnia tutaj błędy wynikające z niewłaściwego projektu od błędów implementacji. Innymi słowy - jeśli mamy błąd bezpieczeństwa nawet przy perfekcyjnej, bezbłędnej implementacji - wówczas jest on kandydatem do kategorii "Insecure Design".
Sam OWASP jako przykład podaje mechanizm pytań i odpowiedzi w procesie resetu hasła. Ze względu na fakt, że często odpowiedzi na pytania można łatwo znaleźć w serwisach społecznościowych (np. na pytanie "jak nazywa się twój kot?"), tego typu mechanizm jest z założenia niebezpieczny.
Analizując listę CWE, skompilowałem listę kilku innych przykładowych błędów, które można by zakwalifikować do tego punktu. Lista znajduje się tutaj: https://sekurak.pl/owasp-top-ten-2021-a04-insecure-design-przeglad-przypadkow/
## Proces S-SDLC
Proces S-SDLC (Secure Software Development LifeCycle) pozwala zminimalizować ryzyko wystąpienia błędów bezpieczeństwa w aplikacji. W skrócie: polega na wdrożeniu odpowiednich zasad rozwoju oprogramowania już od samego początku trwania projektu.
Ciekawą implementację tego procesu daje Microsoft: https://www.microsoft.com/en-us/securityengineering/sdl/practices
## Modelowanie zagrożeń
Istotnym procesem, który pozwala wykrywać potencjalne problemy z projektem aplikacji jest **modelowanie zagrożeń**.
Zgodnie z [Threat Modelling Manifesto](https://www.threatmodelingmanifesto.org/), modelowanie zagrożeń polega na ciągłym zadawaniu sobie czterech pytań:
1. Nad czym pracujemy?
2. Co może pójść źle?
3. Co z tym robimy?
4. Czy robimy to wystarczająco dobrze?
Istotna jest odpowiedź na pierwsze pytanie, bo ona determinuje także odpowiedzi na kolejne. Odpowiedź na "Nad czym pracujemy" może dotykać różnych aspektów aplikacji:
* Możemy patrzeć od strony całej aplikacji.
* Możemy patrzeć od strony kodu.
* Możemy patrzeć od strony logicznych komponentów.
* Możemy patrzeć od strony funkcjonalności aplikacji,
* Możemy patrzeć od strony maszyn wirtualnych.
* Możemy patrzeć od strony infrastruktury chmurowej.
* Możemy patrzeć od strony ....
Inspiracje:
* https://shostack.org/resources/whitepapers/threat-modeling-what-why-how
* https://www.schneier.com/academic/archives/1999/12/attack_trees.html
* https://insights.sei.cmu.edu/blog/threat-modeling-12-available-methods/
Doskonała książka o modelowaniu zagrożeń: https://www.amazon.com/Threat-Modeling-Designing-Adam-Shostack-ebook-dp-B00IG71FAS/dp/B00IG71FAS/ref=mt_other?_encoding=UTF8&me=&qid=
## Checklista
* ✔️ Zweryfikuj, czy stosowany jest proces S-SDLC dotykający procesu rozwoju aplikacji na każdym jej kroku.
* ✔️ Zweryfikuj, czy ciągle dokonywany jest proces modelowania zagrożeń biorący pod uwagę zmiany w aplikacji i ew. zmiany w sposobach działania napastników.
# A07:2025 – Authentication Failures
https://owasp.org/Top10/2025/A07_2025-Authentication_Failures/
Błędy w identyfikacji i uwierzytelnieniu - wszelkiego rodzaju błędu pozwalające na przejęcie dostępu do kont innych użytkowników.
## Dema
**Demo 1. Bruteforce z blokowaniem konta**
https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-account-lock
**Demo 2. Błąd w implementacji 2FA**
https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-broken-logic
**Demo 3. Zatrucie nagłówka Host**
https://portswigger.net/web-security/host-header/exploiting/password-reset-poisoning/lab-host-header-basic-password-reset-poisoning (https://sekurak.pl/pelen-raport-z-realnych-testow-bezpieczenstwa-aplikacji-eventowej-bez-zadnej-cenzury/)
**Demo 4. Błąd z JWT**
```
docker run --rm -p 80:80 jwt
```
* https://sekurak.pl/jwt-biblioteka-auth0-nie-moge-przyjac-twojego-sfalszowanego-podpisu-ale-jestem-uprzejmy-podam-ci-ten-prawidlowy-podatnosc-miesiaca/
* https://sekurak.pl/jwt-security-ebook.pdf
## Checklista
* ✔️ Zweryfikuj, czy aplikacja ma zdefiniowaną politykę haseł. Najbardziej obecnie zalecane podejście do polityki haseł opiera się głównie o wymuszenie długich haseł oraz weryfikację, czy użytkownik nie używa "prostego" hasła.
* ✔️ Zweryfikuj, czy aplikacja nie zdradza poprawności samej nazwy użytkownika (tj. czy wyświetla ogólny komunikat o błędzie typu: "Niepoprawna nazwa użytkownika lub hasło" czy błąd jest bardziej konkretny)
* ✔️ Zweryfikuj, czy proces resetu hasła wymaga potwierdzenia dostępu do konta innym kanałem (np. dostępem do skrzynki emailowej, numeru telefonu itp.)
* ✔️ Zweryfikuj, czy kod generowany w procesie resetu hasła jest generowany z użyciem bezpiecznego kryptograficznie generatora (CSPRNG)
* ✔️ Zweryfikuj, czy każdy krok resetu hasła wymaga podania poprawnego kodu
* ✔️ Zweryfikuj, czy kod do resetu hasła jest jednorazowy
* ✔️ Jesli aplikacja generuje losowe tokeny sesji, zweryfikuj, czy są generowane z użyciem CSPRNG
* ✔️ W przypadku implementacji 2FA, zweryfikuj, czy sesja zostaje w pełni utworzona dopiero po podaniu kodu
* ✔️ W przypadku implementacji JWT, zweryfikuj, czy: i) algorytm "none" jest odrzucany, ii) klucz do podpisu jest wystarczająco długi, iii) token ma określoną ważność
# A08:2025 – Software or Data Integrity Failures
https://owasp.org/Top10/2025/A08_2025-Software_or_Data_Integrity_Failures/
Dotyczy weryfikacji integralności danych i oprogramowania. O integralności danych mówiliśmy już w kontekście kryptografii (i użycia algorytmu HMAC czy AES-GCM).
Opis tego punktu w materiałach OWASP wskazuje, że pokryte są w nim przykładowo następujące scenariusze:
* Aplikacja aktualizuje się automatycznie, pobierając z serwera nowe wersje plików wykonywalnych. Pliki nie mają weryfikowanych podpisów cyfrowych, więc napastnik dysponujący atakiem man-in-the-middle moze spowodować wykonanie wrogiego kodu na serwerze.
* Aplikacja ma zdefiniowaną listę zależności, które są pobierane w trakcie procesu CI/CD. Nie weryfikuje jednak integralności danych - wyniku czego, w trakcie budowania aplikacji pobrane i wykonane zostały inne pliki źródłowe, aniżeli w trakcie dewelopmentu tej aplikacji.
* Aplikacja przechowuje w ciasteczku dane zserializowane - ale nie weryfikuje ich integralności pozwalając na wykonanie dowolnego kodu.
* Aplikacja odnosi się do zewnętrznych plików JS. Ktoś uzyskuje jednak dostęp do serwera, z którego serwowane są te pliki i podmienia je na złośliwe.
## Dema
https://www.programiz.com/php/online-compiler/
```
<?php
// Enter your code here, enjoy!
class Test {
public $x = 150;
public $y = "echo 'ok';";
function __destruct(){
eval($this->y);
}
}
// $obj = new Test();
// $ser = serialize($obj);
// print_r($ser);
// unserialize('O:4:"Test":2:{s:1:"x";i:150;s:1:"y";s:10:"phpinfo();";}');
```
* https://sekurak.pl/php-object-injection-i-zendframework2/
* https://github.com/ambionics/phpggc
* https://github.com/frohoff/ysoserial
* https://github.com/pwntester/ysoserial.net
**Demo 1. Deserializacja**
https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-exploiting-php-deserialization-with-a-pre-built-gadget-chain
**Demo 2. Podmiana pliku JS w aplikacji**
https://jsbin.com/habemapoze/edit?html,output (odświeżyć 10 razy)
(rozwiązanie: https://jsbin.com/zihuvefese/1/edit?html,output)
## Checklista
* ✔️ Upewnij się, że w systemie pakietów (npm, maven, nuget itp.) sprawdzana jest integralność podczas instalowania pakietów. W szczególności dotyczy procesu CI/CD. - (https://sekurak.pl/zaskakujaca-metoda-infekcji-wielkich-i-mniejszych-firm-wykonali-swoj-kod-w-systemach-apple-netflixa-shopify-ubera-paypala-microsoftu-konca-nie-widac/)
* ✔️ Zweryfikuj, że w miarę możliwości aplikacja nie korzysta z tzw. natywnej deserializacji (w zamian może użyć innych formatów, np. json).
* ✔️ W przypadku użycia podpisów cyfrowych, upewnij się, że klucze do podpisu są bezpiecznie przechowywane.
* ✔️ W miarę możliwości ograniczaj odwołania do zewnętrznego kodu JS. Jeśli jest to konieczne, korzystaj z [SubResource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity).
# A09:2025 – Logging & Alerting Failures
https://owasp.org/Top10/2025/A09_2025-Logging_and_Alerting_Failures/
Logowanie pozwala nam określić, jakie dokładne operacje były wykonywane w aplikacji przez użytkowników; zaś monitorowanie pozwala na bieżąco reagować na incydenty.
---
Przykład z życia: kiedyś naszym zadaniem było przeprowadzenie analizy powłamaniowej do pewnego systemu. Jedyne co mieliśmy to access log:
```
1.2.3.4 - - [22/Apr/2020:13:37:37 +0000] "POST /login HTTP/1.1" 200 140 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"
1.2.3.4 - - [22/Apr/2020:13:38:20 +0000] "POST /updateUserData HTTP/1.1" 200 140 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"
1.2.3.4 - - [22/Apr/2020:13:37:20 +0000] "POST /updateUserData HTTP/1.1" 200 140 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"
1.2.3.4 - - [22/Apr/2020:13:37:21 +0000] "POST /updateUserData HTTP/1.1" 200 140 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"
1.2.3.4 - - [22/Apr/2020:13:37:22 +0000] "POST /updateUserData HTTP/1.1" 200 140 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"
1.2.3.4 - - [22/Apr/2020:13:37:23 +0000] "POST /updateUserData HTTP/1.1" 200 140 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"
1.2.3.4 - - [22/Apr/2020:13:37:24 +0000] "POST /updateUserData HTTP/1.1" 200 140 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"
```
Na jego podstawie było de facto niemożliwe, by stwierdzić, co dokładnie zrobił napastnik.
---
**Aby móc z logów wyciągać wnioski, potrzebujemy wiedzieć:**
* Kiedy została wykonana dana akcja (data i godzina, najlepiej w UTC),
* Skąd została wykonana dana akcja (adres IP użytkownika),
* Kto wykonał daną akcję (np. nazwa/identyfikator użytkownika),
* Jaka akcja jest przeprowadzana (np. dostęp do danych rekordu o id=123, podejrzenie danych użytkownika itp.),
* Status akcji (np. powodzenie, błąd),
* Poziom zdarzenia (info, warning, error, critical)
---
**Nie wszystkie dane powinny być jednak w logach przechowywane. Pominąć należy:**
* Numery sesji,
* Hasła,
* Tokeny JWT,
* itp. (ogólnie: dane, które pozwalają przejąć konto użytkownika)
Powód: sam dostęp do logów nie powinien być tożsamy z dostępem do bazy danych (patrz: [przykład Twittera](https://blog.twitter.com/official/en_us/topics/company/2018/keeping-your-account-secure.html)).
---
Aby móc korelować dane z różnych systemów, zaleca się, by korzystać z systemu do centralizacji logów.
Dodatkowy plus centralizacji logów: napastnikowi trudniej będzie zatrzeć ślady po swoich działaniach (bo system ze zcentralizowanymi logami to osobny host, w stosunku do tego, na którym jest teraz napastnik).
---
Przykład pokazujący, dlaczego warto wdrażać monitoring: https://sekurak.pl/wyciek-danych-z-sieci-hotelowej-marriott-wyciekly-dane-ponad-5-milionow-osob/
## Checklista
* ✔️ Zweryfikuj, czy aplikacja loguje wszystkie operacje w niej wykonywane według wskazówek zawartych powyżej dotyczących tego, jakie dane powinny być logowane, a jakie nie.
* ✔️ Zweryfikuj, czy prowadzony jest monitoring tych logów, by wykrywać ew. incydenty.
* ✔️ Zweryfikuj, czy logi są gromadzone w centralnym systemie.
* ✔️ Zweryfikuj, czy logi są gromadzone w trybie read-only/append-only.
* ✔️ Zweryfikuj, czy logi są backupowane.
# A10:2025 Mishandling of Exceptional Conditions
Nowy punkt na liście odnoszący się do zagrożeń związanych nieprawidłową obsługą lub brakiem obsługi wyjątkowych sytuacji co może prowadzić do zatrzymania usługi, nieprzwidywalnego zachowania lub podatności.
**Demo 1. Overflow**
Integer overflow to błąd, który występuje, gdy wynik operacji arytmetycznej na liczbach całkowitych przekracza maksymalną, jaką może przechować dany typ danych
Zobaczmy prosty przykład: <https://onlinegdb.com/vDDlv0V8W>
W jaki sposób w systemie binarnym można reprezentować liczby ujemne?
Jest na to kilka koncepcji, choć najpopularnliajsza to __dopełnienie do dwóch__
$$
\begin{align}
0000\,0101_{2} &= 5_{10} \\
1111\,1011_{2} &= -5_{10}
\end{align}
$$
<https://onlinegdb.com/idU6l5X10d>
W bibliotece [__snappy-java__](https://github.com/xerial/snappy-java) funkcja `compress(char[] input)` ([link](https://github.com/xerial/snappy-java/blob/v1.1.10.0/src/main/java/org/xerial/snappy/Snappy.java#L169)) wywołuje kolejną funkcję wykonując mnożenie przez 2 (char zajmuje 2 bajty) dla podanego inputa:
```java!
public static byte[] compress(char[] input)
throws IOException
{
return rawCompress(input, input.length * 2); // char uses 2 bytes
}
```
```java!
public static byte[] rawCompress(Object data, int byteSize)
throws IOException
{
byte[] buf = new byte[Snappy.maxCompressedLength(byteSize)];
int compressedByteSize = impl.rawCompress(data, 0, byteSize, buf, 0);
byte[] result = new byte[compressedByteSize];
System.arraycopy(buf, 0, result, 0, compressedByteSize);
return result;
}
```
Wywołanie ```Snappy.maxCompressedLength(byteSize)``` powoduje wykonanie kodu z biblioteki [__snappy__](https://github.com/google/snappy) napisanej w języku C++:
```cpp!
size_t MaxCompressedLength(size_t source_bytes) {
...
return 32 + source_bytes + source_bytes / 6;
}
```
Ponieważ funkcja `maxCompressedLength` ([link](https://github.com/google/snappy/blob/main/snappy.cc#L197)) traktuje długość jako liczbę całkowitą bez znaku (8 bajtów), nie zwraca uwagi na to, że może być ona ujemna, i zwraca poprawną wartość, która jest rzutowana na liczbę całkowitą ze znakiem przez silnik Javy. Jeśli wynik jest ujemny, podczas próby alokacji tablicy `buf` zostanie zgłoszony wyjątek `java.lang.NegativeArraySizeException`.
Przykładowo jeśli wykonamy próbę kompresij ```char[0x38300000]``` do `byteSize` funkcji `rawCompress` zostanie przekazana wartość `0x70600000`, która zostanie zwrócona przez bibliotekę snappy jako `0x831aaadc`, która zostanie zinterpretowana przez Java w formie `int` jako:
$$
\begin{align}
1000\,0011\,0001\,1010\,1010\,1010\,1101\,1100_{2} = 83\,1A\,AA\,DC_{16} = -2095404324_{10}
\end{align}
$$
Z drugiej strony, jeśli wynik jest dodatni, tablica `buf` zostanie pomyślnie alokowana, ale jej rozmiar może być zbyt mały do użycia w kompresji, co spowoduje krytyczny błąd naruszenia dostępu (Access Violation).
Jeśli wykonamy próbę kompresij ```char[0x40000000]``` do `byteSize` funkcji `rawCompress` zostanie przekazana wartość `0x80000000`, która jako liczba ujemna typu `int` (-2147483648) zostanie zrzutowana na typ w C++ `size_t` mając wartość `0xffffffff80000000`, następnie przez bibliotekę snappy zostanie zwrócony wynik `0x2aaaaaaa15555587`, który zostanie zinterpretowana przez Java w formie `int` o wartości `0x15555587` jako:
$$
\begin{align}
0001\,0101\,0101\,0101\,0101\,0101\,1000\,0111{2} = 15\,55\,55\,87_{16} = 357913991_{10}
\end{align}
$$
Finalnie prowadząc do błędu buffer overflow ponieważ zarezerwowany bufor `0x15555587` jest mniejszy niż ilość danych `0x80000000`.
Zobaczmy przykład takiej aplikacji: <http://integer-overflow.localhost:1235>
**Demo 2. Ataki na liczby**
Klasa BigInteger, która reprezentuje liczby całkowite o dowolnej precyzji. W przeciwieństwie do standardowych typów liczbowych, takich jak `int` czy `long`, które mają ograniczony zakres wartości, `BigInteger` może przechowywać liczby znacznie większe niż te standardowe typy.

Wiele języków programowania obsługuje taki typ liczbowy, między innymi:
* Java
* JavaScript
* Python (nie ma osobnej klasy, ponieważ typ `int` automatycznie obsługuje liczby całkowite o dowolnej precyzji)
* C#
* PHP
* ...
Ale dlaczego taki typ liczbowy jest potrzebny: <https://jsbin.com/pemesabeka/edit?html,output>, <https://jsbin.com/xusiticega/edit?html,output>
Istnieje analogiczna klasa BigDecimal, która reprezentuje liczby wymierne o dowolnej precyzji. W przeciwieństwie do standardowych typów liczbowych, takich jak (np. `float` i `double`) które mogą prowadzić do błędów zaokrągleń. `BigDecimal` pozwala na precyzyjne reprezentowanie liczb dziesiętnych oraz wykonywanie operacji arytmetycznych z zachowaniem dokładności.

Szybki przykład: <https://jsbin.com/guwajebiwo/edit?html,output>
Notacja naukowa to sposób zapisywania liczb zmiennoprzecinkowych, który umożliwia przedstawienie bardzo dużych lub bardzo małych wartości w bardziej zwięzłej formie. W notacji naukowej liczba jest zapisywana jako iloczyn liczby (zwykle z przedziału od 1 do 10) i potęgi liczby 10.
$$
\begin{align}
x &= a * 10^n \\
a &\in [1, 10) \\
n &\in \mathbb{Z}
\end{align}
$$
Poniżej przedstawiono przykład:
$$
\begin{align}
0,000000000000000000987654321 = 9,87654321 * 10^{-19}
\end{align}
$$
> .Net
>
> Because the BigInteger type is immutable (see Mutability) and because it has no upper or lower bounds, an OutOfMemoryException can be thrown for any operation that causes a BigInteger value to grow too large.
> [learn.microsoft.com](https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-numerics-biginteger)
> [color=#0284c7]
Zobaczmy demo: <http://bank.localhost:1234>
**Demo 3. Czy parametr jest wymagany?**
Atak na zmianę hasła:
<https://ships.lab-08.securitum.net>
## Checklista
* ✔️ Zwsze obsługuj wszystkie wyjątki. Jeśli to możliwe w głównej części programu ustaw przechwytywanie wszystkich wyjątków.
* ✔️ Jeżeli pojawi się wyjątakowa sytuacja zaloguj to zdarzenie do celów analitycznych i debugowania oraz poinformuj użytkownika o wystapieniu błędu ograniczając ilość ujawnianych informacji.
* ✔️ W sytuacji wystąpienia wyjątku w transakcjach z bazą danych wycofaj wszystkie wcześniejsze operacje, jakie zostały wykonane.
* ✔️ Ograniczaj zasoby procsów, skonfiguruj rate limiting, pamiętaj o zwalnianiu zasobów, gdy nie są już potrzebne.
* ✔️ Pamiętaj o zdefiniowaniu generycznej stronie błędów
* ✔️ Zawsze wykonuj walidację względem typu i jeśli to jest możliwe struktury danych jakie przetwarzasz
* ✔️ Zawsze weryfikuj czy wymagane parametry są obecne w żądaniu
# Dziękuję!