Univerzitet u Beogradu Matematički fakultet Seminarski rad predmet: Metodologija naučnog i stručnog rada Najčešći problemi i greške koji se javljaju kod programera pri razvoju softvera Studenti: Profesor: Sanja Petrović dr. Vladimir Filipović Dragana Andrejić Perica Trajkov
34
Embed
Seminarski rad - poincare.matf.bg.ac.rspoincare.matf.bg.ac.rs/~vladaf/Courses/Matf MNSR/Prezentacije... · Univerzitet u Beogradu Matematički fakultet Seminarski rad predmet: Metodologija
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Univerzitet u Beogradu
Matematički fakultet
Seminarski rad
predmet: Metodologija naučnog i stručnog rada
Najčešći problemi i greške koji se javljaju kod
programera pri razvoju softvera
Studenti: Profesor: Sanja Petrović dr. Vladimir Filipović
Dragana Andrejić
Perica Trajkov
UVOD
Kao i svaki drugi rad, tako je i programerski rad podložan greškama. Neke od tih grešaka su
lake za otkrivanje i nisu veoma opasne. Međutim, postoje greške koje ne samo da su česte nego su i
potencijalno veoma opasne ukoliko ih zlonamerni korisnik iskoristi. Lista od 25 najopasnijih
softverskih grešaka iz 2011. godine sastavljena od strane grupe CWE/SANS je lista
najrasprostranjenijih i najkritičnijih grešaka koje mogu da dovede do ozbiljnih ranjivosti u softveru.
Ove greške su često lake za nalaženje, i lake za popravku. Opasne su iz razloga što često dozvoljavaju
napadačima da u potpunosti ili delimično stave softver pod svoju kontrolu, da ukradu podatke, ili da
spreče da softver uopšte radi.
Ova lista najčešdih grešaka može da posluži kao alat za edukaciju i skretanje pažnje
programerima pri kreiranju softvera. Ona je rezultat rada između SANS instituta, MITRE grupe i
mnogih eksperata za softversku bezbednost. Lista iz 2011. godine predstavlja unapređenu i ažuriranu
listu iz 2010. godine.
U ovom radu obrađeno je 15 najčešdih grešaka koje se javljaju u ovoj listi. U nastavku je dat
prikaz tih grešaka po prioritetu bitnosti/javljanja.
Nepravilna neutralizacija specijalnih elemenata korišćenih u SQL naredbama (SQL Injection)
Opis
U računarskom svetu, celokupan softver je veoma povezan sa podacima: smeštanje u
bazu, uzimanje iz baze ili kreiranje informacija iz njih, koje bi se kasnije negde koristile.
Kad bi zlonamerni korisnici mogli na neki način da utiču na SQL upit koji se koristi za
komunikaciju sa bazom podataka, onda bi mogli nastati veliki problemi. Ukoliko se
koristi SQL kod u bezbednosne svrhe poput autentikacije, zlonamerni korisnici bi mogli
da promene logiku SQL upita kako bi zaobišli bezbednosna ograničenja. Upiti se mogu
izmeniti tako da kradu, oštete ili na neki drugi način promene podatke. U 2011. godini
SQL Injection je bio odgovoran za mnoge napade čak i na velike firme poput Sony
Pictures, PBS, MYSQL.com i mnoge druge.
Napad se vrši tako što zlonamerni korisnik unese odreĎeni tekst u polje za unos
teksta, čija vrednost se koristi u nekom SQL upitu. Tekst koji se unosi u polje je takav da
kad se pripoji SQL upitu, zapravo menja upit tako što obično umanjuje restriktivnost
uslova u upitu. Na taj način je moguć pristup veći od onog koji je bio planiran za
posetioca. Ovo se najbolje može objasniti na sledećem primeru:
Primer
Neka neki program u svom kodu koristi sledeći upit:
SELECT * FROM items WHERE owner = <userName> AND itemname =
<itemName>;
S obzirom na to da se SQL upit gradi dinamički nadovezivanjem stringa koji unosi
korisnik na bazni string, tada ukoliko korisnik sa korisničkim imenom boban u polje za
unos koje očekuje itemName, unese:
name' OR 'a'='a
tada upit postaje sledeći:
SELECT * FROM items WHERE owner = 'boban' AND itemname = 'name' OR 'a'='a';
Dodatak OR 'a'='a' prouzrokuje da WHERE klauza uvek ispunjava uslov pa upit postaje
logički ekvivalentan sa mnogo jednostavnijim upitom:
SELECT * FROM items;
Na ovaj način se umesto vraćanja samo onih stavki koje se tiču odreĎenog korisnika, vraćaju
sve stavke u tabeli.
Načini rešavanja problema
Korišćenje slojeva otpora poput Hibernate ili Enerprise Java Beans, koji mogu da
obezbede značajnu zaštitu od ovakvih napada ako se pravilno koriste.
Ukoliko je moguće treba koristiti strukturirane mehanizme koji automatski razdavaju
podatke od koda. Ovi mehanizmi su u mogućnosti da postavljaju znake navoda tamo
gde je potrebno, da vrše odgovarajuće enkodiranje ili automatsku validaciju. Na ovaj
način se ne mora oslanjati na razvijaoce softvera da će paziti prilikom rizičnih SQL
upita.
Pokretanje koda korišćenjem najmanje privilegija koje su neophodne za njegovo
uspešno izvršavanje
Sve sigurnosne provere koje se odvijaju na klijentskoj strani izvršavati i na serverskoj
Ukoliko je neophodno da se koriste dinamičko generisani SQL upiti voditi računa da
se argumenti stave pravilno pod navodnike, i da se koriste iskejp sekvence (escape
sequence) za svaki specijalni karakter
Pretpostaviti najgori slučaj – svaki unos je maliciozan
Nepravilna neutralizacija specijalnih elemenata korišćenih u OS naredbama (OS Injection)
Opis
Softver je često most izmeĎu nekoga izvan i unutrašnjosti operativnog sistema. Kada
se pozove neki drugi program u operativnom sistemu, a dozvole se unosi koji nisu
provereni, pomoću kojih se generiše string komanda, tada se otvara mogućnost da
zlonamerni korisnici izvršavaju sopstvene komande umesto predviĎenih. To može dovesti
do ranjivosti okruženja u kom napadač nema direktan pristup operativnom sistemu, na
primer u veb aplikacijama. Alternativno, ako se bezbednosna slabost javi u programu sa
privilegijama pristupa, ta slabost može da omogući napadaču da koristi komande koje
inače ne bi bile dozvoljene.
Primer
Neka je dat sledeći kod u jeziku PHP:
$userName = $_POST["user"];
$command = 'ls -l /home/' . $userName;
system($command);
Promenljiva $userName se ne proverava od opasnog sadržaja. Napadač može da
postavi sadržaj ove promenljive na neku proizvoljnu komandu, npr:
;rm -rf /
Sada komanda (promenljiva $command) ima sadržaj:
ls -l /home/;rm -rf /
S obzirom na to da je tačka-zarez separator komandi u UNIX sistemima, ova
komande će pored listanja sadržaja direktorijuma izvršiti i brisanje celog fajl sistema.
Načini rešavanja problema
Korišćenje bibliotečkih poziva, umesto eksternih procesa da bi se dobila željena
funkcionalnost
Pokretanje koda u “jail” ili sličnom sandbox okruženju, koje nameće striktne granice
izmeĎu procesa i operativnog sistema. Na ovaj način se može ograničiti pristup
fajlovima ili komandama koje se mogu izvršiti
Svi podaci koji se koriste za generisanje komandi koja će se izvršavati, trebaju se
čuvati što dalje od eksterne kontrole. Npr. u veb aplikacijama ovo podrazumeva
čuvanje podataka lokalno u stanju sesije, umesto slanja podataka klijentu u
sakrivenom polju forme
Sve sigurnosne provere koje se odvijaju na klijentskoj strani izvršavati i na serverskoj
Kopiranje u bafer bez provere veličine ulaza (Buffer Overflow)
Opis
Kopiranje ulaza kome nije proverena njegova veličina u bafer, je jedna od
najjednostavnijih, ali istovremeno i najčešćih grešaka koje se mogu javiti u
programiranju. Takodje, ovo je i jedna od najstarijih grešaka u programiranju. Stanje
prekoračenog bafera se javlja kad program pokušava da smesti više podataka u njega
nego što bafer može da primi, ili kada program pokušava da smesti podatke van granica
bafera. Najjednostavniji tip greške, i najčešći uzrok prekoračenja bafera, je kad program
kopira bafer bez provere koliko se kopira.
Primer
Neka je dat sledeći kod u jeziku C:
char last_name[20];
printf ("Enter your last name: ");
scanf ("%s", last_name);
Problem sa prethodnim kodom je taj da on ne ograničava veličinu unosa od strane
korisnika. Ukoliko korisnik unese nešto što ima više od 20 karaktera, tada će se javiti
prekoračenje bafera, jer niz karaktera u koji se unosi prezime može da sadrži najviše 20
karaktera.
Neka je dat sledeći kod u jeziku C koji pokušava da napravi lokalnu kopiju bafera da
bi mogao da pravi neke izmene nad podacima:
void manipulate_string(char* string){
char buf[24];
strcpy(buf, string);
...
}
Medjutim, programer se ne uverava da li veličina podatka na koji pokazuje pokazivač
string, odgovara lokalnom baferu, i “naslepo” kopira sadržaj pomoći funkcije strcpy koja
je potencijalno nebezbedna.
Načini rešavanja problema
Korišćenje programskih jezika koji ne dozvoljavaju ove slabosti, ili koji obezbeĎuju
konstrukte koji olakšavaju da se ovaj problem primeti. Npr. mnogi jezici koji imaju
svoj menadžer memorije, kao što su Java i Perl, onemogućavaju ovakve situacije.
Neki jezici, poput Ade i C#, obično onemogućavaju prekoračenje bafera ali se ova
opcija može isključiti.
Korišćenje biblioteka koje ne dozvoljavaju da se ovakav problem pojavi (npr. Safe C
String Library - SafeStr)
Kompajliranje programa pomoću kompajlera koji automatski obezbeĎuje zaštitne
mehanizme protiv prekoračenja bafera, time što prijavljuju upozorenje
Vršiti dvostruke provere veličine bafera, paziti o granicama bafera ukoliko se njemu
pristupa u petlji, a ponekad i odsecati ulazne podatke eksplicitno za svaki slučaj
Pretpostaviti da je svaki unos preveliki
Nepravilna neutralizacija ulaza prilikom generisanja Web stranica (Cross-site Scripting)
Opis
Cross-site Scripting (XSS) je jedana od preovlaĎavajućih, upornijih i opasnijih
ranjivosti u web aplikacijama. Ova ranjivost je praktično neizbežna kada kombinujemo
HTTP-ovo nepostojanje stanja, razne podatke i skriptove u HTML-u, dosta prenošenja
podataka izmedju web sajtova, raznovrsne šeme enkodiranja i web pregledače sa dosta
dodataka. Ukoliko nismo pažljivi, napadači mogu da ubace Javascript ili drugi izvršni
kod za pregledač u web stranicu koju naša web aplikacija generiše. Našoj web stranici
pristupaju razni korisnici, čiji pregledači izvršavaju maliciozan skript koji je došao od
nas, a zapravo je delo nekog zlonamernog korisnika. Do ovoga dolazi jer naš veb softver
ne neutrališe, ili loše neutrališe unos od strane korisnika. XSS ranjivost se javlja u
sledećoj okolnosti:
sumnjivi podaci dospeju do web aplikacije
veb aplikacija dinamički generiše veb stranicu koja sadrži ove sumnjive podatke
tokom generisanja stranice, aplikacija ne sprečava da podaci sadrže delove koji su
izvršivi u veb pregledaču, poput JavaScript kodova, dogaĎaja miša, Flash, ActiveX
kontrole itd.
žrtva posećuje generisanu veb stranicu preko veb pregledača, koja sadrži maliciozan
skript
s obzirom na to da skript dolazi sa stranice koja je poslata od istog veb servera, žrtvin
veb pregledač izvršava maliciozan skript
ovo narušava politiku veb pregledača, koja kaže da skriptovi na jednom domenu ne
smeju da pristupe resursima ili da izvršavaju skript sa drugog domena
Primer
Neka je kod u PHP-u koji prikazuje pozdravnu poruku na stranici baziranu na HTTP
Dok programer pristupa fajlovima sa komandama kao što su: /users/cwe/profiles/alice ili
/users/cwe/profiles/bob napadač može koristiti string kao što je: ../../../etc/passwd. Program će
tada generisati putanju: /users/cwe/profiles/../../../etc/passwd. Kada je fajl otvoren operativni
sistem razrešava “../” I pristupa fajlu: /etc/passwd. Kao rezultat napadač može pročitati sadržaj fajla za lozinke.
Načini rešavanja problema
Pretpostavimo da su svi ulazi zlonamerni. Koristimo „prihvati samo dobro poznato“
metod za validaciju unosa. Prilikom vršenja validacije, razmotriti sve potencijalno
odgovarajuće osobine, uključujući dužinu, tip ulaza, pun opseg prihvatljivih
vrednosti, sintaksa, usaglašenost sa pravilima poslovanja. Kao primer logike o
pravilima poslovanja možemo uzeti ulaz „brod“, koji može biti sintaksno ispravan
zato što sadrži samo alfanumeričke karaktere, ali on nije ispravan ukoliko se očekuje
da ulaz sadrži samo imena boja kao što su „crveno i plavo“.
Prilikom validacije imena fajlova treba koristiti stroga pravila koja ograničavaju skup
karaktera koji se mogu koristiti. Ukoliko je moguće treba omogućiti samo korišćenje
jedne tačke „.“ u imenima fajlova. TakoĎe treba korisiti i listu dozvoljenih ekstenzija.
Ne treba se oslanjati isključivo na mehanizme za filtriranje koji prepoznaju
potencijalno opasne karaktere. Na primer, filtriranje karaktera „/“ je nedovoljna
zaštita ukoliko sistem podržava i karakter „\“ kao separator za direktorijume.
Za svaku bezbednosnu proveru koja se vrši na strani klijenta treba obezbediti da se ta
ista provera vrši i na strani servera. Napadači mogu zaobići provere na strani klijenta
promenom vrednosti nakon što su provere izvršene.
Koristiti zaštite za aplikacije koje mogu da detektuju ovakve vrste napada. Ovo može
biti korisno u slučajevima gde se kod ne može lako popraviti.
Kada je skup prihvatljivih objekata, kao što su imena fajlova i url-ovi, ograničen ili
poznat treba osmisliti mapiranje koje vrši preslikavanje iz tog skupa fiksiranih
ulaznih vrednosti u skup stvarnih vrednosti i tako odbijati sve ulaze koji se nisu
odgovarajući.
Obezbediti da poruke o greškama sadrže minimalno detalja koji su od koristi samo
odreĎenim osobama i nikome više. One ne treba da otkriju metode koje su korišćene
u detekciji greške. Takve informacije mogu biti korisne u poboljšanju napada.
Ukoliko koristite PHP treba konfigurisati aplikaciju tako da se ne koriste globalne
promenljive (register_globals)
Preuzimanje koda bez prevere integriteta
Opis
Nije nepoznata stvar to da ukoliko preuzmemo neki kod sa Interneta i pokrenemo ga
mi ustvari verujemo da taj kod nije zarazan (zlonameran). Čak i ukoliko pristupamo samo
sajtovima kojima verujemo, napadači će učiniti sve da izmene taj kod pre nego što doĎe do
nas. Oni mogu, na primer, da preuzmu (hakuju) sajt za preuzimanje podataka i tako naterati
sistem da vrši preusmeravanje na neki drugi sajt i sl. Ovo se može dogoditi i u slučajevima
kada se preuzima sopstveni proizvod. Kada do ovoga doĎe softver će pokrenuti kod koji nije
očekivao, što je loše po nas, a odlično za napadače.
Primer
U ovom primeru učitava se eksterna klasa iz lokalnog poddirektorijuma:
URL[] classURLs= new URL[]{
new URL("file:subdir/")
};
URLClassLoader loader = new URLClassLoader(classURLs);
Class loadedClass = Class.forName("loadMe", true, loader);
Ovaj kod ne proverava da li je klasa koja je učitana ona očekivana. Napadač može promeniti
klasu u neki izvršni zlonamerni kod.
Načini rešavanja problema
Proveravati DNS-ove kako bi se otkrile razne obmane
Šifrovati kod pouzdanim algoritmima pre prenosa
Može biti korisno koristiti alate ili zaštite koji vrše proveru integriteta prilikom
preuzimanja koda
Pogrešna autorizacija
Opis
Dok je nedostatak odobrenja pristupa prilično opasan, neodgovarajuća odobrenja
mogu biti jednako problematična. Programeri mogu pokušati da kontrolišu pristup odreĎenim
resursima, ali je to uglavnom implementirano tako da se može zaobići. Na primer, odreĎena
osoba je jednom prilikom bila prijavljena na nekoj web aplikaciji i programeri mogu sačuvati
ovu informaciju u kolačiću. Izmenom kolačića, napadač može pristupiti drugim resursima.
Alternativno, programer može izvršiti autorizaciju isporukom koda koji se izvršava na strani
klijenta, ali napadač može koristiti izmenjenog klijenta koji u potpunosti uklanja proveru.
Načini rešavanja problema
Uveriti se da svoju kontrolu pristupa radite u skladu sa svojom poslovnom logikom
Korišćenje proverenih biblioteka
Kod web aplikacija, proveriti da mehanizam za kontrolu pristupa radi ispravno na
serverskoj strani za svaku stranicu
Koristite mogućnosti kontrole pristupa vašeg operativnog sistema i servera i
definišite svoju listu pristupa u skladu sa njima. Koristiti politiku „podrazumevana
odbijanja“ prilikom definisanja kontrola pristupa
Zaključak
Kao što se vidi iz prethodnog, greške su raznih tipova. Međutim, ono što je zajedničko za njih je to da je potrebno samo malo nepažnje da bi do njih došlo. S druge strane, zajedničko je i to što je, na svu sredu, uglavnom lako njihovo ispravljanje. Ukoliko ih ne ispravimo to često može imati nesagledive posledice, naročito za ozbiljnije softverske projekte. Zbog toga nam ova lista može služiti i kao mali podsetnik, i veliko upozorenje da pazimo prilikom izgradnje softvera. Čak i naizgled najbezazlenije radnje i komande mogu u sebi kriti veoma opasna mesta koja mogu biti zloupotrebljena od onih kojima je posao da zloupotrebljavaju takve nedostatke. Izgradnja softvera de uvek predstavljati borbu između dveju strana, i svaka od tih strana de onu drugu terati da se poboljšava i unapređuje. Ta brorba de trajati bez prestanka.