Poglavlje 12: Sigurnost i privatnost po dizajnu
Priča za početak. U martu 2017. godine organizacija koja održava popularnu biblioteku za web aplikacije, Apache Struts, objavila je upozorenje i ispravku za ozbiljnu rupu: napadač je mogao, posebno sastavljenim zahtjevom, natjerati server da izvrši njegov kod. Ispravka je bila dostupna 7. marta 2017. Američka kreditna agencija Equifax, koja čuva finansijske podatke o stotinama miliona ljudi, koristila je Struts na jednom od svojih portala. Interno upozorenje da treba ugraditi ispravku je poslano, ali ispravka nije ugrađena, a automatsko skeniranje koje je trebalo naći neažurirane servere nije ih pronašlo. Od sredine maja napadači su kroz tu rupu ulazili u sistem i iznosili podatke, a Equifax je to primijetio tek krajem jula. Ukradeni su imena, datumi rođenja, brojevi socijalnog osiguranja i adrese za oko 147 miliona ljudi (prva objava govorila je o 143 miliona). Direktor je podnio ostavku, a firma je platila ogromne nagodbe. Napadači nisu koristili nikakvu genijalnu novu tehniku. Ušli su kroz vrata za koja je brava već bila kupljena, ali nije bila ugrađena.
U poglavlju 10 rekli smo da je API vrata sistema i spomenuli četiri brave: HTTPS, token, provjeru prava i ograničenje broja zahtjeva. Ovo poglavlje ide dublje. DeliveryApp čuva adrese i telefone kupaca, istoriju njihovih narudžbi i obavlja plaćanje. To su podaci koje neko može htjeti ukrasti, i obaveze koje zakon nameće. Prvo učimo osnovne ciljeve sigurnosti i kako se korisnik prijavljuje i šta smije. Zatim upoznajemo najčešće slabosti web aplikacija i učimo da prijetnje tražimo sistematski, modelom STRIDE. Na kraju govorimo o privatnosti: šta kaže GDPR, šta znači privatnost po dizajnu i šta se radi kad se incident ipak desi. Na praktičnoj nastavi pravimo model prijetnji za DeliveryApp, heširamo lozinke i popravljamo SQL injekciju.
Literatura. Osnovna literatura predmeta:
- B. Popović, K. Kuk: Informacioni sistemi, Kriminalističko-policijski univerzitet, Beograd, 2017.
- J. S. Valacich, J. F. George: Modern Systems Analysis and Design, 9th ed., Pearson, 2020.
- L. Jelenković: Sustavi za rad u stvarnom vremenu – skripta, FER, Zagreb, 2015.
- D. Milićev: Programiranje u realnom vremenu – skripta, Beograd, 2002.
- V. Kovačević, M. Popović: Sistemska programska podrška u realnom vremenu 1, FTN, Novi Sad, 2013.
Riječi ovog poglavlja.
- Povjerljivost, integritet, dostupnost (CIA) – tri cilja sigurnosti: podatak vide samo ovlašteni, niko ga ne mijenja neovlašteno, i dostupan je kad treba.
- Autentifikacija – provjera ko je korisnik („jeste li vi zaista K-01?”).
- Autorizacija – provjera šta korisnik smije („smije li K-01 vidjeti N-1002?”).
- Heš – jednosmjerna funkcija koja od lozinke napravi „otisak” iz kojeg se lozinka ne može vratiti.
- So (salt) – slučajan dodatak lozinki prije heširanja, različit za svakog korisnika.
- Višefaktorska autentifikacija (MFA) – prijava s dva ili više dokaza: nešto što znate, imate ili jeste.
- Ranjivost – slabost u sistemu koju napadač može iskoristiti.
- OWASP Top 10 – lista deset najčešćih i najopasnijih rizika web aplikacija.
- SQL injekcija – napad u kojem unos korisnika postane dio SQL naredbe.
- Model prijetnji – sistematski spisak onoga što napadač može pokušati i kako se branimo.
- STRIDE – šest vrsta prijetnji: lažno predstavljanje, mijenjanje, poricanje, otkrivanje, uskraćivanje usluge, povećanje ovlaštenja.
- Lični podatak – svaki podatak koji se odnosi na osobu koja se može prepoznati (ime, adresa, telefon, istorija narudžbi).
- GDPR – opšta uredba Evropske unije o zaštiti podataka o ličnosti.
- Privatnost po dizajnu – zaštita privatnosti ugrađena u sistem od prvog crteža, a ne dodata na kraju.
- Incident – događaj u kojem je sigurnost narušena (npr. curenje podataka).
Ciljevi poglavlja. Nakon poglavlja možete: objasniti povjerljivost, integritet i dostupnost na primjeru DeliveryApp; razlikovati autentifikaciju i autorizaciju; objasniti zašto se lozinka čuva kao spori heš sa solju i izračunati koliko traje pogađanje lozinke; objasniti višefaktorsku prijavu; napraviti tabelu uloga i prava i prepoznati grešku „tuđa narudžba po broju”; nabrojati nekoliko rizika s liste OWASP Top 10; pokazati SQL injekciju i popraviti je parametrizovanim upitom; napraviti model prijetnji STRIDE za DeliveryApp i ocijeniti rizike; navesti principe i prava iz GDPR-a; primijeniti privatnost po dizajnu na podatke DeliveryApp; opisati revizijski trag i postupak kod incidenta.
Plan poglavlja – Sedmica 12: tri časa teorije i tri časa praktične nastave
| Čas | Sadržaj | Na času |
|---|---|---|
| Teorija 1 | 12.1–12.3 CIA; prijava i lozinke; uloge i prava | 21 sekunda ili 242 dana; K-02 i N-1001 |
| Teorija 2 | 12.4–12.6 OWASP; SQL injekcija; STRIDE | ' OR '1'='1; šest prijetnji DeliveryApp |
| Teorija 3 | 12.7–12.9 GDPR; privatnost po dizajnu; trag i incidenti | NZ-5; 72 sata |
| Praksa 1–3 | STRIDE tabela; heš lozinke; popravka injekcije; provjera prava | sigurnost/ |
Dio 1 – Ciljevi, prijava i prava
12.1 Povjerljivost, integritet, dostupnost
Sigurnost informacionog sistema ima tri osnovna cilja, koji se pamte po engleskoj skraćenici CIA (confidentiality, integrity, availability):
| Cilj | Pitanje | Šta bi narušilo cilj u DeliveryApp |
|---|---|---|
| Povjerljivost | Vide li podatak samo oni koji smiju? | neko pročita adrese i telefone svih kupaca |
| Integritet | Je li podatak tačan i nepromijenjen bez dozvole? | neko promijeni cijenu Margarite na 0,10 € ili stanje tuđe narudžbe |
| Dostupnost | Radi li sistem kad treba? | napadač zatrpa server zahtjevima u podne i niko ne može naručiti |
Ova tri cilja često se međusobno vuku. Najpovjerljiviji sistem je isključen računar u sefu, ali on nije dostupan. Projektant traži ravnotežu prema vrijednosti podatka: adresa kupca traži više zaštite od jelovnika, koji je ionako javan.
Uz CIA se često dodaju još dva cilja: autentičnost (zna se ko je poslao podatak) i neporecivost (onaj ko je nešto uradio ne može kasnije poreći, npr. restoran ne može reći „nikad nismo prihvatili N-1001”, jer postoji trag). Oba se oslanjaju na revizijski trag (12.9).
Slika iz života: banka. Povjerljivost je da niko ne vidi tuđi račun. Integritet je da se stanje računa ne može promijeniti bez naloga. Dostupnost je da bankomat radi i u nedjelju.
Ukratko.
- Tri cilja sigurnosti su povjerljivost, integritet i dostupnost (CIA).
- Povjerljivost: vide samo ovlašteni; integritet: niko ne mijenja bez dozvole; dostupnost: radi kad treba.
- Ciljevi se vuku jedan protiv drugog, pa se zaštita bira prema vrijednosti podatka.
- Autentičnost i neporecivost oslanjaju se na revizijski trag.
12.2 Prijava: ko ste vi?
Autentifikacija je provjera ko je korisnik. Najčešći način je lozinka, i najčešća greška projektanta je kako je čuva.
Lozinka se nikad ne čuva kao tekst
Ako baza čuva lozinke kao običan tekst, svako ko dođe do baze (napadač, ali i nepošten zaposleni) zna lozinke svih kupaca. A ljudi koriste istu lozinku na više mjesta, pa napadač ulazi i u njihovu e-poštu i banku. Zato NZ-3 DeliveryApp kaže: lozinka se čuva samo kao heš.
Heš (hash) je jednosmjerna funkcija: od lozinke napravi niz znakova („otisak”), a iz otiska se lozinka ne može izračunati nazad. Pri prijavi server ne poredi lozinke, nego otiske: izračuna heš unesene lozinke i uporedi ga sa sačuvanim.
Dva dodatka su obavezna:
- So (salt). Prije heširanja lozinki se doda slučajan niz, različit za svakog korisnika, i sačuva uz otisak. Tako dva korisnika s istom lozinkom „Ljeto2026!” imaju različite otiske, i napadač ne može unaprijed napraviti tabelu otisaka čestih lozinki.
- Spora funkcija. Obične heš funkcije (npr. SHA-256) su pravljene da budu brze, a to ovdje pomaže napadaču. Za lozinke se koriste namjerno spore funkcije: PBKDF2, bcrypt, scrypt ili Argon2. One otisak računaju hiljadama puta zaredom.
U Pythonu (modul hashlib dolazi uz jezik):
import hashlib, os
so = os.urandom(16) # 16 slučajnih bajtova, novi za svakog korisnika
otisak = hashlib.pbkdf2_hmac("sha256", "Ljeto2026!".encode(), so, 600_000)
# u bazu idu so i otisak, nikad sama lozinkaBroj 600 000 je broj ponavljanja; na običnom računaru jedan ovakav otisak traje oko petine sekunde. Korisnik to ne primijeti pri prijavi, a napadaču to znači ogromno usporenje.
Koliko traje pogađanje
Zašto je brzina toliko važna? Uzmimo lozinku od 8 malih slova engleske abecede. Mogućih lozinki ima:
\[ N = 26^8 \approx 2{,}09 \times 10^{11} \]
Čemu služi. N je broj pokušaja koje napadač u najgorem slučaju mora isprobati. Ako je ukradena baza s brzim hešom, napadač s jakom grafičkom karticom može probati oko 10¹⁰ lozinki u sekundi, pa mu treba 2,09 × 10¹¹ / 10¹⁰ ≈ 21 sekunda. Ako je heš spor, recimo 10⁴ pokušaja u sekundi, treba mu 2,09 × 10¹¹ / 10⁴ ≈ 2,09 × 10⁷ sekundi, a to je oko 242 dana, za samo jednu lozinku. Duža lozinka pomaže još više: četiri nasumične riječi iz spiska od 7776 riječi daju 7776⁴ ≈ 3,7 × 10¹⁵ mogućnosti, što i kod sporog heša znači hiljade godina.
Broj za pamćenje. Ista lozinka od 8 malih slova: 21 sekunda uz brzi heš, oko 242 dana uz spori. Projektant bira kako se lozinka čuva; korisnik bira samo lozinku.
Višefaktorska prijava
Lozinka može biti ukradena (lažnom stranicom, preko ramena, iz druge provaljene baze). Zato se za važne naloge traži višefaktorska autentifikacija (MFA): dva ili više dokaza različite vrste:
- nešto što znate (lozinka, PIN);
- nešto što imate (telefon s aplikacijom za kodove, sigurnosni ključ);
- nešto što jeste (otisak prsta, lice).
NZ-3 traži da se restoran prijavljuje dvofaktorski, jer nalog restorana može mijenjati jelovnik i cijene i prihvatati narudžbe. Za kupca je dvofaktorska prijava ponuđena, ali nije obavezna, da ne oteža prvu narudžbu (NZ-4); projektant je ovdje svjesno vagao sigurnost i upotrebljivost.
Ukratko.
- Autentifikacija provjerava ko je korisnik.
- Lozinka se nikad ne čuva kao tekst, nego kao spori heš sa solju (PBKDF2, bcrypt, Argon2).
- Lozinka od 8 malih slova pada za oko 21 sekundu uz brzi heš, a za oko 242 dana uz spori.
- Višefaktorska prijava traži dokaze različite vrste; DeliveryApp je traži od restorana.
12.3 Prava: šta smijete?
Autorizacija je provjera šta prijavljeni korisnik smije. Najčešći način je kontrola pristupa po ulogama (RBAC, role-based access control): prava se ne daju osobi, nego ulozi, a osoba dobija ulogu.
| Radnja | Kupac | Restoran | Dostavljač | Administrator |
|---|---|---|---|---|
| čitati jelovnik | da | da | da | da |
| napraviti narudžbu | da | – | – | – |
| čitati narudžbu | samo svoju | samo za svoj restoran | samo dodijeljenu | sve |
| vidjeti adresu kupca | svoju | ne (vidi samo ulicu za procjenu) | samo dok dostavlja | da, uz trag |
| prihvatiti ili odbiti narudžbu | – | samo za svoj restoran | – | – |
| mijenjati cijene jela | – | samo svoja jela | – | – |
| otkazati narudžbu | samo svoju, po PP-6 | – | – | da, uz razlog |
Primijetite riječ „svoju”. Najčešća i najopasnija greška autorizacije nije da kupac može ono što smije samo restoran, nego da kupac može tuđe ono što smije za svoje. Klasičan primjer: kupac K-02 je prijavljen i čita svoju narudžbu na adresi /v1/narudzbe/N-1002. Šta ako u adresu upiše N-1001? Ako server provjerava samo „je li korisnik prijavljen”, K-02 vidi adresu i telefon kupca K-01. Ova greška ima ime: nesigurna direktna referenca na objekat (engleski insecure direct object reference, IDOR). Ispravka je jednostavna, ali se mora napisati na svakom mjestu: server provjeri da je narudzba.kupac == prijavljeni_korisnik, i ako nije, vrati 403 ili 404.
Ovo je princip najmanje potrebnog pristupa (least privilege): svako dobija samo prava potrebna za posao. Dostavljač vidi adresu kupca samo dok vozi narudžbu, a ne cijelu istoriju kupca. Slika iz života: ključevi u hotelu. Gost ima ključ samo od svoje sobe, sobarica od soba na svom spratu, a samo direktor od sefa.
Ukratko.
- Autorizacija provjerava šta prijavljeni korisnik smije; najčešće se radi po ulogama (RBAC).
- Najopasnija greška je da korisnik vidi tuđe podatke mijenjanjem broja u adresi (IDOR).
- Server na svakom zahtjevu provjerava i ulogu i vlasništvo nad podatkom.
- Princip najmanje potrebnog pristupa: svako dobija samo prava potrebna za posao, kao ključevi u hotelu.
Provjeri se.
- Koja je razlika između autentifikacije i autorizacije? – Autentifikacija provjerava ko je korisnik, a autorizacija šta smije.
- Zašto se uz heš lozinke dodaje so? – Da isti lozinke imaju različite otiske i da napadač ne može unaprijed napraviti tabelu otisaka.
- Šta treba provjeriti kad K-02 traži N-1001? – Da narudžba pripada prijavljenom kupcu; ako ne pripada, odbiti zahtjev.
Dio 2 – Ranjivosti i model prijetnji
12.4 OWASP Top 10
OWASP (Open Worldwide Application Security Project) je otvorena zajednica stručnjaka za sigurnost web aplikacija. Najpoznatiji njen rad je OWASP Top 10: lista deset najčešćih i najopasnijih rizika, napravljena iz stvarnih podataka o napadima. Lista se obnavlja svakih nekoliko godina; verzija iz 2021. godine izgleda ovako:
| Oznaka | Rizik | Primjer u DeliveryApp | Odbrana |
|---|---|---|---|
| A01 | Pokvarena kontrola pristupa | K-02 čita N-1001 (12.3) | provjera vlasništva na svakom zahtjevu |
| A02 | Kriptografski propusti | lozinke kao tekst; HTTP bez S | spori heš sa solju; samo HTTPS |
| A03 | Injekcija | SQL injekcija u pretrazi jela (12.5) | parametrizovani upiti |
| A04 | Nesiguran dizajn | server vjeruje cijeni iz aplikacije (poglavlje 9) | model prijetnji od početka |
| A05 | Pogrešna podešavanja | ostavljena testna lozinka administratora | lista za provjeru pri isporuci |
| A06 | Ranjive i zastarjele komponente | neažurirana biblioteka (Equifax, 2017) | spisak komponenti i redovno ažuriranje |
| A07 | Propusti u prijavi | neograničeno pogađanje lozinke | zaključavanje nakon 5 pokušaja, MFA |
| A08 | Narušen integritet softvera i podataka | ažuriranje se preuzima bez provjere potpisa | potpisani paketi, provjera izvora |
| A09 | Propusti u bilježenju i nadzoru | napad traje mjesecima neprimijećen | revizijski trag i upozorenja (12.9) |
| A10 | Krivotvorenje zahtjeva sa servera (SSRF) | server preuzima „sliku jela” s adrese koju je upisao napadač | dozvoljene adrese, provjera unosa |
Priča s početka poglavlja je udžbenički primjer rizika A06: biblioteka je imala poznatu rupu, ispravka je postojala, ali nije ugrađena, i niko nije imao pouzdan spisak gdje se ta biblioteka sve koristi. Moderan Python projekat ima desetine biblioteka, a svaka ima svoje biblioteke. Zato tim vodi spisak komponenti (fajl requirements.txt je njegov početak) i koristi alate koji automatski javljaju kad se za neku od njih objavi ranjivost (npr. GitHub Dependabot).
Ukratko.
- OWASP Top 10 je lista deset najčešćih rizika web aplikacija, iz stvarnih podataka.
- Na vrhu verzije iz 2021. je pokvarena kontrola pristupa, a slijede kriptografski propusti i injekcija.
- Equifax 2017. je primjer rizika A06: poznata ranjivost u neažuriranoj biblioteci.
- Tim vodi spisak komponenti i koristi alate koji javljaju nove ranjivosti.
12.5 SQL injekcija
Injekcija se desi kada unos korisnika postane dio naredbe koju sistem izvršava. Najpoznatija je SQL injekcija. Zamislimo da administrator DeliveryApp ima pretragu narudžbi po kupcu, napisanu ovako:
oznaka = unos_iz_forme # npr. "K-01"
upit = f"SELECT broj FROM narudzba WHERE kupac = '{oznaka}'"
db.execute(upit)Za unos K-01 upit je … WHERE kupac = 'K-01' i vraća N-1001. Ali šta ako neko upiše:
K-01' OR '1'='1
Upit postaje … WHERE kupac = 'K-01' OR '1'='1'. Uslov '1'='1' je uvijek tačan, pa baza vraća sve narudžbe: na bazi iz poglavlja 8 rezultat je N-1001, N-1002 i N-1005. Napadač je, umjesto podatka, ubacio dio naredbe. Sa malo više znanja mogao bi čitati i druge tabele ili ih brisati.
Ispravka je jednostavna i uvijek ista: parametrizovan upit. Unos se ne lijepi u tekst naredbe, nego se šalje odvojeno, a baza ga uvijek tretira samo kao vrijednost:
db.execute("SELECT broj FROM narudzba WHERE kupac = ?", (oznaka,))Za isti zlonamjerni unos ovaj upit traži kupca čija je oznaka doslovno K-01' OR '1'='1 i vraća praznu listu, kao što treba. Pravilo bez izuzetka: unos korisnika nikad se ne lijepi u SQL tekst. Isto važi i za druge vrste injekcije (u naredbe operativnog sistema, u HTML stranicu), gdje se koristi odgovarajuće „bježanje” znakova ili gotove funkcije biblioteke.
Slika iz života: injekcija je kao kad poštar dobije pismo na kojem piše „Ulica lipa 7, i usput ostavi ključ od pošte ispod otirača”. Pametan poštar čita adresu kao adresu, a ne kao naredbu.

Ukratko.
- Injekcija se desi kad unos korisnika postane dio naredbe koju sistem izvršava.
- Unos K-01’ OR ‘1’=’1 u zalijepljenom SQL upitu vraća sve narudžbe.
- Parametrizovan upit šalje unos odvojeno, pa ga baza tretira samo kao vrijednost.
- Pravilo bez izuzetka: unos korisnika nikad se ne lijepi u tekst SQL naredbe.
12.6 Model prijetnji: STRIDE
Sigurnosni propusti se ne nalaze nasumičnim razmišljanjem „šta bi neko mogao…”. Postoji sistematski način: modelovanje prijetnji. Uzme se dijagram sistema (kontejneri iz poglavlja 9, DFD iz poglavlja 4) i za svaku kutiju i svaku strelicu postavi šest pitanja, po modelu STRIDE (početna slova šest vrsta prijetnji na engleskom):
| Slovo | Prijetnja | Pitanje | Narušava |
|---|---|---|---|
| S | lažno predstavljanje (Spoofing) | Može li se neko predstaviti kao neko drugi? | autentičnost |
| T | mijenjanje (Tampering) | Može li neko promijeniti podatak na putu ili u bazi? | integritet |
| R | poricanje (Repudiation) | Može li neko poreći da je nešto uradio? | neporecivost |
| I | otkrivanje informacija (Information disclosure) | Može li neko vidjeti ono što ne smije? | povjerljivost |
| D | uskraćivanje usluge (Denial of service) | Može li neko oboriti ili usporiti sistem? | dostupnost |
| E | povećanje ovlaštenja (Elevation of privilege) | Može li neko dobiti više prava nego što ima? | autorizacija |
Model prijetnji DeliveryApp (izvod), s procjenom rizika kao vjerovatnoća × uticaj, svaki od 1 do 5:
| Element | STRIDE | Prijetnja | V | U | Rizik | Odbrana |
|---|---|---|---|---|---|---|
| prijava restorana | S | napadač pogodi lozinku restorana i mijenja cijene | 3 | 4 | 12 | dvofaktorska prijava, zaključavanje |
| aplikacija → server | T | izmijenjena aplikacija šalje „ukupno 0,50 €” | 4 | 4 | 16 | server sam računa cijenu (pogl. 9) |
| prihvatanje narudžbe | R | restoran tvrdi da nije prihvatio N-1001 | 2 | 3 | 6 | revizijski trag sa vremenom i nalogom |
| API narudžbi | I | K-02 čita N-1001 mijenjanjem broja | 4 | 4 | 16 | provjera vlasništva (12.3) |
| API u podne | D | stotine lažnih zahtjeva u sekundi | 2 | 5 | 10 | ograničenje broja zahtjeva, balanser |
| uloga kupca | E | kupac pozove PATCH …/stanje i sam prihvati narudžbu |
3 | 3 | 9 | provjera uloge na svakoj adresi |
Najveći rizici (16) obrađuju se prvi. Primijetite da dvije najveće prijetnje već imaju odbranu ugrađenu ranije, u arhitekturi i API-ju: to je smisao sigurnosti po dizajnu. Prijetnja koja je otkrivena na crtežu košta jednu rečenicu; prijetnja koju otkrije napadač košta kao kod Equifaxa.

Ukratko.
- Model prijetnji sistematski traži opasnosti na dijagramu sistema.
- STRIDE ima šest vrsta prijetnji: lažno predstavljanje, mijenjanje, poricanje, otkrivanje, uskraćivanje usluge i povećanje ovlaštenja.
- Rizik je vjerovatnoća × uticaj; najveći rizici se obrađuju prvi.
- Prijetnja otkrivena na crtežu košta rečenicu, a otkrivena od napadača mnogo više.
Provjeri se.
- Kojem riziku OWASP-a pripada Equifax 2017? – A06, ranjive i zastarjele komponente.
- Kako se popravlja SQL injekcija? – Parametrizovanim upitom: unos se šalje odvojeno i baza ga tretira samo kao vrijednost.
- Koje slovo STRIDE-a opisuje da kupac sam prihvati svoju narudžbu? – E, povećanje ovlaštenja.
Dio 3 – Privatnost
12.7 Lični podaci i GDPR
Sigurnost pita kako zaštititi podatke od napadača. Privatnost pita nešto drugo: smijemo li uopšte prikupljati i koristiti podatak o čovjeku, za šta, i koliko dugo. DeliveryApp zna gdje kupac živi, kada je kod kuće, šta jede i koliko troši. To su lični podaci: svaki podatak koji se odnosi na osobu koja se može prepoznati, direktno (ime) ili posredno (adresa, telefon, istorija narudžbi).
U Evropskoj uniji obradu ličnih podataka uređuje GDPR (General Data Protection Regulation, Opšta uredba o zaštiti podataka), usvojena 2016. i primjenjuje se od 25. maja 2018. Uredba važi i za firme izvan EU koje nude usluge ljudima u EU. Bosna i Hercegovina ima vlastiti zakon o zaštiti ličnih podataka i Agenciju za zaštitu ličnih podataka, a propisi se usklađuju s GDPR-om; za projektanta je najjednostavnije projektovati po načelima GDPR-a, jer su ona danas evropski standard.
GDPR počiva na sedam načela obrade:
| Načelo | Značenje | U DeliveryApp |
|---|---|---|
| zakonitost, poštenje, transparentnost | jasan razlog i jasno obavještenje | kupac vidi zašto tražimo telefon (za dostavljača) |
| ograničenje svrhe | podatak samo za svrhu zbog koje je prikupljen | adresa za dostavu, ne za prodaju oglašivačima |
| smanjenje količine podataka | samo podaci koji su zaista potrebni | ne tražimo datum rođenja ni JMBG |
| tačnost | podaci tačni i ažurni | kupac sam ispravlja adresu |
| ograničenje čuvanja | ne duže nego što treba | NZ-5: adresa i telefon se brišu 12 mjeseci nakon posljednje narudžbe |
| cjelovitost i povjerljivost | zaštita od gubitka i neovlaštenog pristupa | heš lozinki, uloge, HTTPS, kopije |
| odgovornost | firma mora moći dokazati da poštuje načela | zapis obrade, revizijski trag, procjena uticaja |
Osoba čiji su podaci ima i prava: da sazna koje podatke o njoj čuvamo (pravo na pristup), da ih ispravi, da zatraži brisanje („pravo na zaborav”, uz izuzetke, npr. račune koje zakon traži da se čuvaju), da ih dobije u prenosivom obliku i da prigovori obradi. Za projektanta to znači konkretne funkcije u sistemu: dugme „Preuzmi moje podatke” i „Obriši moj nalog” nisu ukras, nego zakonska obaveza.
Kazne za teže povrede GDPR-a mogu dostići 20 miliona eura ili 4 % godišnjeg svjetskog prometa firme, šta god je veće.
Česta zabluda. „Ako je podatak dobro zaštićen, smijemo ga čuvati koliko hoćemo.” Ne. Najbolje zaštićen podatak je onaj koji ne postoji. Podatak koji se ne prikupi ne može ni procuriti. Zato su smanjenje količine podataka i ograničenje čuvanja i sigurnosne, a ne samo pravne mjere.
Ukratko.
- Privatnost pita da li smijemo prikupljati i koristiti podatak, za šta i koliko dugo.
- Lični podatak je svaki podatak o osobi koja se može prepoznati, i adresa i istorija narudžbi.
- GDPR se primjenjuje od 25. maja 2018. i ima sedam načela, među njima ograničenje svrhe, smanjenje količine i ograničenje čuvanja.
- Prava na pristup, ispravku, brisanje i prenosivost postaju funkcije sistema.
- Kazne mogu dostići 20 miliona eura ili 4 % godišnjeg prometa.
12.8 Privatnost po dizajnu
Privatnost po dizajnu (privacy by design) znači da se zaštita privatnosti ugrađuje u sistem od prvog crteža, a ne dodaje na kraju. GDPR to traži izričito (zaštita podataka „integrisana i zadana”). U praksi, za DeliveryApp:
- Pitati za svaku kolonu „treba li nam?”. Prolazimo kroz šemu baze iz poglavlja 8. Telefon kupca treba dostavljaču. Datum rođenja ne treba nikome, pa ga nema.
- Zadana postavka je najprivatnija. Kupac koji ne promijeni ništa ne dobija reklamne poruke; mora ih sam uključiti.
- Prikazati samo onoliko koliko treba. Restoran vidi „Ulica lipa” za procjenu, ali ne broj kuće i telefon. Dostavljač vidi punu adresu tek kad preuzme narudžbu, i više je ne vidi nakon isporuke.
- Pseudonimizacija u izvještajima. Mjesečni izvještaj restorana pokazuje „kupac K-01”, a ne ime i adresu. Ko analizira prodaju, ne treba znati ko je jeo.
- Automatsko brisanje. NZ-5 nije obećanje u dokumentu, nego zadatak koji se svake noći pokreće i briše adrese i telefone kupaca bez narudžbe u posljednjih 12 mjeseci. Plaćeni računi ostaju koliko zakon traži, ali bez nepotrebnih detalja.
- Procjena uticaja. Prije nove funkcije koja obrađuje mnogo ličnih podataka (npr. „preporuke jela na osnovu istorije”), tim zapiše šta se obrađuje, zašto, koji su rizici i kako se smanjuju.
Ovo je ista ideja kao kod sigurnosti i kvaliteta u cijeloj knjizi: što ranije, to jeftinije. Kolona koja nikad nije napravljena ne treba se brisati, štititi ni objašnjavati agenciji.
Ukratko.
- Privatnost po dizajnu ugrađuje zaštitu od prvog crteža, kako traži i GDPR.
- Za svaku kolonu se pita „treba li nam”, a zadana postavka je najprivatnija.
- Svaka uloga vidi samo onoliko koliko treba, a izvještaji koriste pseudonime.
- NZ-5 je noćni zadatak koji automatski briše stare adrese i telefone.
12.9 Revizijski trag i incidenti
Ni najbolje projektovan sistem nije savršen. Zato se projektuje i ono što se dešava kad nešto pođe naopako.
Revizijski trag (audit log) je zapis važnih događaja: ko je, kada, s kojeg uređaja i šta uradio. U DeliveryApp se bilježe prijave i neuspjele prijave, promjene stanja narudžbe (lista istorija iz poglavlja 7 je početak), promjene cijena i jelovnika, svaki pristup administratora ličnim podacima kupca, i izvoz ili brisanje podataka. Revizijski trag služi trima stvarima: da se otkrije napad (OWASP A09; Equifax je napad primijetio tek nakon više od dva mjeseca), da se dokaže ko je šta uradio (neporecivost), i da se istraži sporna situacija. Sjetite se britanske pošte iz poglavlja 1: poslovođe nisu imale način da dokažu šta je sistem zaista radio.
Trag ima svoja pravila: ne smije sadržati lozinke ni pune brojeve kartica; zaštićen je od izmjene (dopisuje se, ne prepravlja); i i sam je lični podatak, pa se ni on ne čuva vječno.
Incident je događaj u kojem je sigurnost narušena, npr. curenje adresa kupaca. Tim treba imati plan odgovora na incident prije nego što zatreba, kao vatrogasnu vježbu:
- Otkriti i zaustaviti – izolovati pogođeni dio (isključiti ranjivu adresu, promijeniti ključeve).
- Procijeniti – šta je procurilo, čiji podaci, koliko ljudi.
- Obavijestiti – GDPR traži da se nadzorni organ obavijesti u roku od 72 sata od saznanja o povredi ličnih podataka, a pogođene osobe bez nepotrebnog odlaganja ako je rizik za njih visok.
- Popraviti i naučiti – otkloniti uzrok i zapisati pouku, bez traženja krivca, nego uzroka (isti duh kao retrospektiva u poglavlju 2).
Iz stvarnog svijeta. Kod Equifaxa je od dostupne ispravke (7. mart 2017) do početka napada (sredina maja) prošlo više od dva mjeseca, a od početka napada do otkrivanja (kraj jula) još oko dva i po mjeseca. Svaki od tih perioda je mogao biti kraći: brže ažuriranje komponenti, pouzdaniji spisak gdje se koja biblioteka koristi, i nadzor koji primijeti neobično mnogo podataka koji izlaze iz sistema.

Ukratko.
- Revizijski trag bilježi ko je, kada i šta uradio, i služi da se otkrije napad, dokaže radnja i istraži spor.
- Trag ne sadrži lozinke ni brojeve kartica, zaštićen je od izmjene i ni on se ne čuva vječno.
- Plan odgovora na incident ima četiri koraka: zaustaviti, procijeniti, obavijestiti i naučiti.
- GDPR traži obavještenje nadzornog organa u roku od 72 sata od saznanja o povredi.
Provjeri se.
- Šta znači načelo ograničenja čuvanja? – Lični podaci se ne čuvaju duže nego što je potrebno za svrhu; u DeliveryApp NZ-5 briše adrese nakon 12 mjeseci.
- Kada dostavljač vidi punu adresu kupca? – Tek kad preuzme narudžbu, i ne poslije isporuke.
- U kojem roku se po GDPR-u obavještava nadzorni organ o povredi podataka? – U roku od 72 sata od saznanja.
Praktična nastava – sigurnost DeliveryApp
Cilj je napraviti model prijetnji za DeliveryApp, ispravno čuvati lozinke, pokazati i popraviti SQL injekciju i dodati provjeru prava u API. Fajlovi idu u folder sigurnost/ i kod/.
Korak 1 – Model prijetnji STRIDE
- Uzmite dijagram kontejnera iz poglavlja 9 (slika 9.5) ili svoj iz
arhitektura/. - U
sigurnost/stride.mdnapravite tabelu kao u 12.6: za svaki kontejner i svaku strelicu bar jednu prijetnju, slovo STRIDE, vjerovatnoću, uticaj, rizik i odbranu. Najmanje 10 redova, bar jedan za svako slovo. - Poredajte po riziku i za tri najveća napišite korisničku priču ili zadatak za backlog (npr. „Kao restoran, želim dvofaktorsku prijavu…”).
Korak 2 – Heš lozinke
U kod/lozinke.py napišite dvije funkcije i provjerite ih:
import hashlib, hmac, os
def sacuvaj(lozinka):
so = os.urandom(16)
otisak = hashlib.pbkdf2_hmac("sha256", lozinka.encode(), so, 600_000)
return so.hex() + ":" + otisak.hex() # ovo ide u bazu
def provjeri(lozinka, zapis):
so_hex, otisak_hex = zapis.split(":")
novi = hashlib.pbkdf2_hmac("sha256", lozinka.encode(), bytes.fromhex(so_hex), 600_000)
return hmac.compare_digest(novi.hex(), otisak_hex)
z = sacuvaj("Ljeto2026!")
print(provjeri("Ljeto2026!", z), provjeri("ljeto2026!", z)) # True False
print(sacuvaj("Ljeto2026!") == z) # False: nova so, novi otisakIzmjerite koliko traje jedan poziv sacuvaj (modul time) i izračunajte koliko bi trajalo isprobavanje svih 26⁸ lozinki tom brzinom. Funkcija hmac.compare_digest poredi otiske u stalnom vremenu, da napadač ne može po brzini odgovora pogađati koliko je znakova tačno.
Korak 3 – SQL injekcija i popravka
- U
kod/injekcija.pynapravite bazu izschema.sqlipodaci.sql(poglavlje 8) i napišite ranjivu pretragu sa f-stringom iz 12.5. - Pozovite je s unosom
K-01i s unosomK-01' OR '1'='1. Očekivano: prvi daje[('N-1001',)], drugi[('N-1001',), ('N-1002',), ('N-1005',)]. - Popravite pretragu parametrizovanim upitom i ponovite: drugi unos sada daje
[].
Korak 4 – Provjera prava u API-ju
U kod/api.py (poglavlje 10) dodajte jednostavnu provjeru: zahtjev za GET /v1/narudzbe/{broj} mora imati zaglavlje X-Kupac (u stvarnom sistemu to bi bio token). Ako se X-Kupac ne poklapa s kupcem narudžbe, server vraća 403. Provjerite iz HTTPie:
http GET :8000/v1/narudzbe/N-1001 X-Kupac:K-01 # 200
http GET :8000/v1/narudzbe/N-1001 X-Kupac:K-02 # 403
Zapišite zašto je ovo samo vježba (zaglavlje može lažirati svako) i šta bi u pravom sistemu zamijenilo X-Kupac (token iz prijave, 10.9).
Korak 5 – Pregled privatnosti
U sigurnost/privatnost.md prođite kroz sve kolone šeme baze iz poglavlja 8 i za svaku upišite: je li lični podatak, zašto nam treba (svrha), ko je smije vidjeti i koliko dugo se čuva. Predložite bar jednu kolonu koja se može ukloniti ili skratiti, i napišite SQL naredbu za noćni zadatak NZ-5 (brisanje adresa kupaca bez narudžbe u posljednjih 12 mjeseci).
Korak 6 – AI kao napadač (opcionalno)
Dajte AI asistentu opis API-ja DeliveryApp (adrese iz 10.3, bez stvarnih podataka) i zatražite: „Kao etički napadač, navedi deset načina da se ovaj API zloupotrijebi i kako se svaki sprečava.” Uporedite s vlastitom STRIDE tabelom i dodajte prijetnje koje ste propustili. Ne šaljite AI-ju stvarne lozinke, tokene ni podatke o ljudima.
Rezultat koji se predaje: sigurnost/stride.md, sigurnost/privatnost.md, kod/lozinke.py s mjerenjem, kod/injekcija.py s ranjivom i popravljenom verzijom i ispisom oba rezultata, te izmijenjen kod/api.py s provjerom 403.
Vježbe
Vježba za studenta 1 – CIA.
Koji cilj sigurnosti je narušen? a) dostavljač D-2 objavi na društvenoj mreži adresu poznate osobe koja je naručila pizzu; b) neko promijeni cijenu dostave u bazi na 0,00 € za sve; c) server ne radi dva sata u petak u podne zbog napada; d) restoran tvrdi da nikad nije odbio narudžbu N-1007, a trag ne postoji.
Rješenje. a) povjerljivost; b) integritet; c) dostupnost; d) neporecivost (i autentičnost), zbog nedostatka revizijskog traga.
Vježba za studenta 2 – pogađanje lozinke.
Lozinka ima 10 znakova od malih i velikih slova i cifara (62 moguća znaka). Koliko je mogućnosti, i koliko bi u najgorem slučaju trajalo pogađanje uz 10⁴ pokušaja u sekundi?
Rješenje. 62¹⁰ ≈ 8,4 × 10¹⁷ mogućnosti. Uz 10⁴ u sekundi: 8,4 × 10¹⁷ / 10⁴ = 8,4 × 10¹³ s, a godina ima oko 3,15 × 10⁷ s, pa je to oko 2,7 miliona godina.
Vježba za studenta 3 – autentifikacija ili autorizacija.
- Kupac unese pogrešnu lozinku pet puta i nalog se zaključa na 15 minuta. b) Restoran R-2 ne može prihvatiti narudžbu restorana R-1. c) Restoran mora unijeti kod iz aplikacije na telefonu poslije lozinke. d) Dostavljač ne vidi adresu narudžbe koja mu nije dodijeljena.
Rješenje. a) autentifikacija (zaštita prijave); b) autorizacija; c) autentifikacija (drugi faktor); d) autorizacija (najmanje potrebnog pristupa).
Vježba za studenta 4 – STRIDE.
Za strelicu „sistem plaćanja → server: potvrda plaćanja (webhook)” iz poglavlja 10 napišite dvije prijetnje sa slovom STRIDE i odbranom.
Rješenje. Primjeri: S – napadač pošalje lažnu potvrdu „plaćeno” na našu adresu; odbrana: provjera potpisa poruke tajnim ključem koji znamo samo mi i sistem plaćanja, i provjera iznosa kod sistema plaćanja. T – napadač na putu promijeni iznos u potvrdi; odbrana: HTTPS i potpis poruke. D – napadač zatrpa adresu webhooka lažnim porukama; odbrana: ograničenje broja zahtjeva i prihvatanje samo s poznatih adresa.
Vježba za studenta 5 – privatnost po dizajnu.
Marketinški tim predlaže: „Čuvajmo zauvijek sve adrese i istoriju narudžbi, da kupcima šaljemo ponude prema tome šta su jeli.” Koja načela GDPR-a ovo krši i kako napraviti prijedlog koji ih poštuje?
Rješenje. Krši ograničenje čuvanja (zauvijek), ograničenje svrhe (adresa je za dostavu, ne za marketing) i vjerovatno smanjenje količine podataka. Prijedlog koji poštuje načela: ponude samo kupcima koji su to sami uključili (pristanak, zadana postavka isključeno), koriste se samo kategorije jela, bez adrese, a podaci se brišu po NZ-5; kupac može u svakom trenutku isključiti ponude i preuzeti ili obrisati svoje podatke.
Sažetak u pet rečenica
- Sigurnost ima tri cilja, povjerljivost, integritet i dostupnost, a Equifax 2017. pokazuje kako jedna neugrađena ispravka biblioteke može otkriti podatke oko 147 miliona ljudi.
- Autentifikacija provjerava ko je korisnik, pa se lozinke čuvaju kao spori heš sa solju (8 malih slova: 21 sekunda uz brzi, oko 242 dana uz spori heš), a restoran se prijavljuje dvofaktorski.
- Autorizacija provjerava šta korisnik smije, po ulogama i vlasništvu nad podatkom, jer je najčešća greška da kupac mijenjanjem broja u adresi vidi tuđu narudžbu.
- OWASP Top 10 navodi najčešće rizike, SQL injekcija se sprečava parametrizovanim upitima, a model prijetnji STRIDE sistematski traži opasnosti na dijagramu sistema i ocjenjuje ih kao vjerovatnoću puta uticaj.
- Privatnost po GDPR-u i privatnost po dizajnu traže da se prikuplja samo potrebno, prikazuje samo onima kojima treba i briše na vrijeme (NZ-5), uz revizijski trag i plan za incident s obavještenjem u roku od 72 sata.