Web bezbednost srednje

A01:2025 — Pogrešna kontrola pristupa

Kontrola pristupa odlučuje ko sme da uradi šta u aplikaciji. Kada ta logika nije ispravno implementirana, napadač može pristupiti resursima ili akcijama za koje nema nikakvu dozvolu — bez hakovanja, bez eksploita, samo promenom broja u URL-u.

Ovo nije egzotična ranjivost. Od 2021. OWASP je svrstava na prvo mesto liste najčešćih web ranjivosti, ispred SQL injektovanja i XSS-a. Pojavljuje se u ~94% testiranih aplikacija, i razlog je banalan: provera pristupa je laka za zaboraviti, a teška za sistematski testirati.

U ovoj lekciji ćeš sresti tri konkretna oblika te ranjivosti na simuliranoj bankarskoj aplikaciji. Svaki deo krije jedan fragment zastave — trebaće ti sva tri da je složiš.


1. IDOR — kada ID govori previše

Zamisli bankarsku aplikaciju. Prijavljen/a si, i tvoj profil se učitava sa /api/profil?user_id=7. Server uzme broj 7, potraži korisnika u bazi i vrati podatke.

Problem nastaje ako server ne proveri da li korisnik koji šalje zahtev zaista sme da vidi podatke tog korisnika. Bez te provere, dovoljno je promeniti broj u URL-u — i gledaš tuđi nalog. Ovo se zove IDOR (Insecure Direct Object Reference).

Tvoj ID kao korisnik je 7. Promeni broj i vidi šta server vraća:

bankasrb.rs/api/profil?user_id=

Fix je jedna linija — server mora da proveri vlasništvo pre nego što vrati podatke:

ranjivo
def profil():
    uid = request.args['user_id']
    # nema provere vlasništva
    return get_user(uid)
ispravno
def profil():
    uid = request.args['user_id']
    if uid != session['user_id']:
        abort(403)
    return get_user(uid)

2. Admin panel bez dozvole

Drugi čest problem: programer zaštiti admin panel tako što ga sakrije — ne prikaže link u navigaciji regularnim korisnicima. Ali ruta i dalje postoji na serveru, i niko ne proverava da li imaš pravo da joj pristupiš.

Ovo je razlika između skrivanja i zabrane. Napadaču link ne treba. Dovoljno je da zna ili pogodi URL, a adrese kao /admin, /admin/users, /dashboard/admin su potpuno predvidive.

Prijavi se kao obični korisnik Marko, pa pokušaj direktno otvoriti admin rutu koja nije u meniju:

bankasrb.rs/login

Razlika između ranjivog i ispravnog koda je samo u tome šta tačno proveravaš:

ranjivo
# proverava samo da li je ulogovan
if not session['logged_in']:
    return redirect('/login')
return all_users()
ispravno
# proverava i ulogu
if session.get('role') != 'admin':
    abort(403)
return all_users()

3. Path traversal — izlaz iz sandboxa

Aplikacija nudi preuzimanje izveštaja putem parametra: /download?fajl=izvestaj.pdf. Server uzme vrednost tog parametra i doda je na putanju do uploads foldera.

putanja = "/var/www/uploads/" + request.args['fajl']

Normalan zahtev čita /var/www/uploads/izvestaj.pdf — sve u redu. Ali sekvenca ../ znači „idi jedan folder gore". Bez sanitizacije unosa, napadač može napustiti dozvoljeni direktorijum i pročitati bilo koji fajl do kog aplikacija ima pristup — konfig fajlove, privatne ključeve, lozinke.

Uploads folder je na /var/www/uploads/. Cilj ti je /etc/tajni_kljuc.txt. Razmisli koliko puta treba da se vratiš gore:

/download?fajl=
— odgovor servera —

Ispravka: koristiti os.path.realpath() i proveriti da li razrešena putanja počinje dozvoljenim direktorijumom, ili još bolje — koristiti ID-jeve umesto imena fajlova (?fajl_id=42), što potpuno eliminiše problem.


Složi zastavu

Kada pronađeš sva tri fragmenta, složi ih zajedno i unesi kompletnu zastavu:

1 ???
+
2 ???
+
3 ???

Završi sve tri ranjivosti da otključaš kompletnu zastavu.

📝 Provera Znanja

Unesite svoj odgovor ispod da biste proverili da li ste razumeli lekciju: