Predrag Cujanović

Menu

Sigurni php kod

Par saveta za pisanje sigurnog php koda.

 

Zaštita od SQL Injection-a

evo kao primjer jedan jednostavni kod: (traženje usera u bazi)

 

<form action=“.“ method=“post“>

<input type=“text“ name=“username“ />

<input type=“submit“ name=“sbm“ value=“Search!“ />

</form>

 

(…)

 

mysql_connect(„localhost“, „guest“);

mysql_selectdb(„db1″);

 

$mysql = mysql_query („SELECT * FROM `table` WHERE USER = $_POST[‘username’]„);

$arr = mysql_fetch_array ($mysql);

 

foreach ($arr as $key=>$entry)

echo „$key-$entry <br >“;

 

Ovaj kod ne da je nesiguran, nego kao da trazi da ga netko probije…. problem je da šta god korisnik upiše u polje, to će SQL server i izvrišti….. šta bi npr bilo da koristnik upiše:

„nitko; DROP TABLE `table`“ i klikne Search!???? mysql query bi izgledao: „SELECT * FROM `ṫable` WHERE USER = nitko; DROP TABLE `table`;“. Drugim rjecima, ode vam tablica…. nema je!

 

Kako se zaštititi…. vrlo jednostavno. Koristite funckiju za escapanja zlih znakova kod mysql-a…. Ta se funkcija zove: mysql_real_escape…. tako da bi siguran kod izgledao:

 

$mysql = mysql_query („SELECT * FROM `table` WHERE USER = „. mysql_real_escape($_POST[‘username’]);

 

Ali ni to nije to….. u ponekim serverima, ima jedna stvar koja može naštetiti kod korištenja funkcije…. ta se stvar zove MagicQuotes…. To je automatsko escapanje ugrađeno u PHP, ali JE NESIGURNO I NEEFIKASNO…. zato, na ponekim serverima, trebate disablat to…. ili možete koristiti sljedeću funckiju:

 

function safe($value) {

if (get_magic_quotes_gpc()) //dali je magic quptes ukljucen

$value = stripslashes($value); //ako je, ponisti sta je napravio

if (!is_numeric($value)) //dali nije numericka vrjednost (dali je string?)

$value = „‘“ . mysql_real_escape_string($value) . „‘“; //ako je string, escapaj ga kako spada

return $value;

}

 

i sada koristite:

$mysql = mysql_query („SELECT * FROM `table` WHERE USER = „. safe($_POST[‘username’]);

 

IZBJEGAVANJE XSS NAPADA

Kao prvo…. XSS napadi su najčešće moguci zato jer developter stranice misli da je siguran….

1. Nemojte stavljati podatke u hidden-e….. hidden elementi se jednako lako mogu promjeniti kao i obični…

2. Svaki dio HTML koda se može promjeniti HTML javascriptom….

3. Provjeravajte ulazne podatke….

Nemojte misliti da ako npr stavite 5 vrjednosti u jedan <select> da korisnik neće moći promjeniti u nešto šta nije na listi….. provjerjavajte SVE!

Evo primjera XSS napada….. odite na

https://testasp.vulnweb.com/Search.asp

Upisite nesto…. primjetite da ono sta ste napisali, isto to ce vam i ispisati negdje na stranici….

Probajte mu sada upisati neki html kod…. npr <i>Bok</i> i primjetite da je Bok nakošen…. e sada… ajde otvorite ovaj URL:

https://tinyurl.com/xsstestCujanovic-com

Eto, to je najjednostavniji primjer XSS napada… ovom metodom ljudi vam mogu ukrasti cookie-e, a da ni ne primjetite… a ako vam ukradu cookie, ukradu vam i PHPSESSID pomoću kojeg se mogu logirati na stranicu kao vi…

Jedan najjednostavniji način obrane:

HTML escape…. znaći, ako vi i pokušate ubaciti mu html kod, on to escape-a, te prikaže kod, tj. ne izvrši ga…. možete koristiti htmlentitles….

<h1>Siguran search</h1>

<form action=’.’ method=’post’>

<input type=“text“ name=“q“ />

<input type=“submit“ name“s“ value=“Trazi“ />

</form>

 

(…)

 

<?php

if ($_POST[‘s’] == „Trazi“) {

 

$q = $_POST[‘q’];

 

echo „Pretražujem vaš zahtjev: „. htmlentitles($q); // KORISTITE HTMLENTITLES

require_once („mysql_connect.php“); //spajanje na bazu

$mysql = mysql_query („SELECT * FROM `table` WHERE `sadrzaj` LIKE ‘%“.safe($q).“%’“); //safe funkcija iz proslog primjera….

(…)

 

} else die(„error“);

 

?>

 

KORISTITE HTMLENTITLES SVAKI; ALI BAS SVAKI PUTA KADA DIO KORISNIKOVG UPITA SE ISPISUJE NA EKRAN!!!

 

Zaštita prilikom otvaranja filova

Evo nesigurnog koda:

<?php

if (isset ($_POST[‘s’]) {

$f = fopen („logs/“.$_POST[‘num’].“txt“, „r“); //npr logs/3.txt

$content = fread ($f, filesize($f)); //čita cijeli file

echo $content;

 

} else {

echo „

 

<h1>Pogledajte vaše log fileove</h1>

 

<form method=’post’ action=’logs.php’>

 

Broj file-a: <input type=’text’ name=’num’ />

<input type=’submit’ name=’s’ />

 

</form>“;

}

?>

 

Eh, recimo da se fajl zove logs.php…. postoji 2 napada na tu foru…. Prvi je dictionary traversal, a drugi poison null byte….

dictionary traversal je: ../ otvara prehodni direktorij. Npr, ako korisnik gore upiše „../sifre“, otvara logs/../sifre.txt, tj sifre.txt…..

 

poison null byte je: kada u php-u koristite stringove, sve poslje null-byte-a se zanemaruje….. npr, ako korisnik upise: „../login.php%00″, fopen će otvarati /logs/../login.php\0.txt (%00 je hex, URL zapis, \0 je php null byte zapis), sta dođe na login.php….. tj, vidi kod i sve druge fajlove vaše aplikacije

 

Kako se zaštititi, jako jednostavno….napravite funkciju koja provjerava dali ima znakova: ‘\’, ‘/’, te provjerava dali je extenzija prava…. kao parametre uzima string, i array dozvoljenih extenzija

 

<?php

function safe_file ($str, $ext) {

//ako ima znakova ‘\’, ‘/’ vrati 0

 

for ($i = 0; $i < strlen($str); $i++) {

switch ($str[$i]) {

case ‘\\’:

case ‘\/’:

 

return 0;

}

}

 

//extenzija iz string-a

$temp = split (‘\.’, $str);

$EXT = $temp[count($temp)-1];

 

$b = false;

 

//dali extenzija iz stringa postoji u nizu dopuštenih

for ($i = 0; $i < count($ext); $i++) {

 

if (strtolower($EXT) == strtolower($ext[$i])) {

$b = true;

break;

}

}

 

return $b;

 

}

 

i sada otvarajte file pomoću:

 

if (safe_file($_POST[‘num’], array(„txt“,“doc“,“xls“))) $f = fopen („logs/“.$_POST[‘num’], „r“);

else die („mrs ca, hakeru!“);

 

Zaštita prilikom korištenja system naredbe

Iako jednostavna, ova naredba može jednako jednostavno ubiti vaš system….

Postoji milijun načina kako iskoristiti tu naredbu… pa da ne oduglvlačim, zaštititi se možete pomoću escapeshellcmd naredbe:

system (escapeshellcmd(„cal $_POST[‘bok’];“));

 

 

Mislite da je MD5 siguran???

Jeste li culi za pojam Rainbow tablice??? Ako ne, onda sigurno ne znate da Rainbow tablice služe za jako brzo crackiranje šifri…. postoje terabajti i terabajti Rainbow tabolica pogotovo za pozdane algoritme hashiranja…. najpoznatiji je MD5….. MD5 se može crackirati u roku od par skundi i to preko web-a, bez ikakvih alata….

To ne znaci da je MD5 nesiguran (ili SHA1 ili DES ili slicno)…. samo ga treba ispravno koristiti…

Koristite i neke druge metode, osim najpopularnijih MD5, i SHA-1

npr…. koristite:

crypt ($salt, $password),

ili bilokoji mhash algoritam,

u kombinariji…. samo nije jako

 

1. Koristite salt:

md5 ($salt.$password); -> $salt neka bude vaš tajni niz znakova…. npr salt kao „&!sad7Fh#.ć“ bi trebao biti sasvim dovoljan (koristite salt od min 5 znaka, i koristite svakakve znakove u njemu, inaće nema efekta)…. zašto salt pomaže???

zato jer korisnici često upisuju nesigurne šifre…. šifre tipa 6 znaka i manje engleske abecede….. uz pomoć salta…. password je duži, a i ima više znakova…. sada se haker mora mučiti sa 100-njak znaka…

 

2. MD5 je brz…. prebrz…. i prepoznat…. koristite kombinacije, tipa:

md5(sha1($salt.$password)); ili crypt($salt, md5($password)); ili nesto drugo će sasvim izbaciti Rainbow tablice iz igre…. korištenjem salta se izbacuju BruteForceri i Dictionary napadi…. znaći, sigurno je .) Ostaje jos samo Social Engineering, sniffanje i Keylogeri… to je istina malo off topic, ali je jako važno…

 

Spremanje osjetljivih podataka (Siguran login)

1. Cookie su fora… ali se mogu jako lako mjenjati….

Npr, ako imate varijable tipa: username, password, authorized i sl…. Haker promjeni cookie, i usao je…. Ili, haker ukrade cookie-e i vidi korisnikovu šifru i username….. znaći, cookie samo za podatke koji mogu biti vidljivi svima, i koji ne štete nikome kada ih se mjenja…

 

2. Spremanje šifre: NIKADA, ali baš NIKADA NE SPREMAJTE ŠIFRU U ČITLJIVOM OBLIKU…. NEMOJTE NITI KORISTITI SAMO VLASTITE ENKRIPCIJE…. KORISTITE HASH FUNKCIJE!!!! (tek onda možete vlastitu enkripciju/dekripciju na hash ubaciti)

Također…. sve šifre i podatke o korisniku, u nikakav fajl, nikakvi cookie-i…. zato služe baze podataka….. jedino šta može ići u neku fajlu (ili cookie) je korisnikova konfiguracija, tj, kako da se stranica prikazuje… (tipa shema, broj poruka, itd)….

 

Siguran login/register stranica:

<?php

session_start(); //mora biti prva linija u php kodu…

 

echo „<html><head>“;

if (isset($_SESSION[‘user’])) { //dali je korisnik logiran?

echo „<link href=’“.$_COOKIE[‘style’].“.css’ rel=’stylesheet’ type=’text/css’ />“; //učitavanje CSS-a pomoću COOKIE-a….. ovo nemože naštediti sistemu, pa može biti u COOKIE-u

 

(….)

 

} else if (isset ($_POST[‘login’])) { //dali se korisnik želi logirat???

$hash = crypt ($salt, md5($_POST[‘psw’])); //korištenje kao opisano gore…

 

require_once („mysql_connect.php“); // spajanje na bazu

$mysql = mysql_query („SELECT * FROM `table` WHERE `username` = „.safe($_POST[‘user’]).“ AND `psw` = „.safe($hash).“;“); //korištenje safe funkcije od gore

 

if (mysql_num_rows($mysql) == 1) { //dali je neđen točno 1 korisnik koji koristi određeni username i password?

$_SESSION[‘user’] = $_POST[‘user’]; //postavljanje sessiona

include („user_pages.php“);

} else if (mysql_num_rows($mysql) == 0) { //ako nije

echo „Wrong login!!!“;

include („login.html“);

} else //ako ih je nađeno više, javi grešku….

die (“ SYSTEM ERROR!!! ERROR NUMBER: 666; PLEASE REPORT THIS TO ADMINS“);

} else if (isset ($_POST[‘register’])) { //ako se želi registrirati

$mysql = mysql_query („SELECT * FROM `table` WHERE `username` = „.safe($_POST[‘username’]).“;“);

if (mysql_num_rows ($mysql) > 0) { //provjerava dali se username koristi

echo „Username exist!!! Choose another“;

include („register.html“);

} else {

$hash = crypt ($salt, md5($_POST[‘psw’])); // duplo hashiranje

mysql_query („INSERT INTO `table` (`username`, `psw`) VALUES („.safe($_POST[‘username’]).“, „. safe($hash). „);“); //ubacivanje korisnika u bazu

echo „Register sucessful! Please login“;

include („login.html“);

}

}

?>

 

Sigurno slanje mail-a

Recimo da imate jednu jednostavnu mail skriptu:

mail($_POST[‘to’], $_POST[‘subject’], $_POST[‘message’], „From: „. $_POST[‘from’]„);

Mislim da je ovdje sve jasno….. Sada 2 razloga zašto je ovo nesigurno:

1) Korisnik može mjenjati headere (zadnji argument funkcije….. npr, može upisati u „from“ polje tuđi email, i par headera koje želi (npr da poruka bude u HTML formatu))

2) Korisnik može ubaciti HTML u poruku…. znaći, ljudi bi mislili da ste vi poslali poruku sa virusom

Obranite se ovom funkcijom i escapajte text poruke:

 

<?php

function safemail ($header) {

$header = str_replace („\n“, „\0″, $header); // mjenja svaki \n u nullbyte

$header = str_replace („\r“, „\0″, $header); // mjenja svaki \r u nullbyte

return $header;

}

 

$to = $_POST[‘to’];

$subject = $_POST[‘subject’];

$msg = htmlspecialchars($_POST[‘message’]); //htmlspecialchars je slično htmlentitles-u, ali puno lijepše i pogodnije za mail…. mjenja samo opasne znakove

$header = „From: „. safemail ($_POST[‘from’]);

 

mail ($to, $subject, $msg, $header);

?>

 

Protokol

Pratite protokol….. (http, ftp, https, ftps itd)….

Prije nego upisujete neke povjerljive podatke, pogledajte protokol: http i ftp protokoli se mogu snifati (pogodovo ako koristite wlan), tj. gledati sve pakete koje vi šaljete i na taj način saznati vašu šifru….. Pogotovo oprez u Web kafićima i sl. javnim mjestima… Ako ste na javnom mjestu i koristite wlan, ne upisujte šifre ako protokol nije https, ftps ili bilokoji koji ne završava na s

 

Keyloggeri

To su ili programi (virusi) ili uređaji koji prate vaše signale sa tipkovnice, i šalje hakeru…. Znaći, haker vidi sve šta se tipka…. Najjednostavnija zaštita je:

Pamet u glavu (pazite šta otvarate)

Antivirusni

Firewall (ali dobro podešen! Ne samo instalirati, i to je to…. već konfigurirati vlastitioj konfiguraciji, vlastitim željama)

Provjeravajte žicu tipkovnice (keylogger alati su veličine USB porta….. npr, ako koristite USB-PS/2 adapter, nebi niti primjetili da vam netko postavi keylogger…

 

Social Engineering

Iako ne spada programiranje, mislim da je potrebno pisati o tome… Za one koji neznaju…. Social Engineering je metoda manipuliranja korisnikom u svrhu zloupotrabe podataka… Tj, haker na prevaru pokušava iz vas izvući podatke… Iako mislete da ste vi pametni, (ne kazem da niste), da vas nece prevariti itd….. reći ću vam, razmislite opet….. Social Engineering se koristi jako često i gotovo je svaki puta uspješan…. hakeri su ljudi koji znaju na sta treba ciljat… evo par smjernica:

1. Ne govorite privatne podatke nikome!!! Haker, ako ne vas, može prevariti vaše informatički-nepismene prijatelje, kolege, zaposlenike itd…

2. Ne zapisujte šifre!!!

3. Ako nekome baš morate dati šifru, napravite mu ograničena dopuštenja…. ADMINISTRATORSKU ŠIFRU SAMO VI TREBATE ZNATI!

4. Administratori ZNAJU hash vaše šifre, znaći mogu pristupiti vašem accountu i bez da znaju vašu šifru…. Administrator vas NIKADA neće tražiti šifru!

5. Pazite da nitko ne gleda dok tipkate šifru….. samo informacija koliko je dugačka i koji su sve znakovi u igri puno pomažu hakeru….

6. Email -> leglo virusa…. preko e-maila, može vam se dati URL koji krade cookie, može vam se ubaciti keylogeri, može vam se ukrasti podaci i sl….. Ne čestitke, nagradne igre, i ostale gluposti….. to su vam virusi, ako niste znali. Ili ako ste mislil da vam neće biti ništa…

7. NISTE SIGURNI!!!! NIKADA! to uvijek imajte na umu….. u informatici nitko nije siguran. Nemojte misliti da hakeri ciljaju samo na velike stvari, da ste vi nezanimljivi u toj priči…. možda baš vas iskoristi kao prolaz….. često se koristi tuđom IP adresom i ostalime kako bi se mislilo da ste vi napadač….i kao primjer može poslužiti i jedan virus nedavno izašao, mislim da se zove Storm… Koristi računala po cijelom svijetu… možda bas vaš i moj… a znate kako se širi?? Dobijete lijepu roza e-mail poruku, tipa Sretno Valentinovo, i kliknite ovjde da bi vidjeli karmu, horoskop, i sl….. znaći, ljudi su ipak dosta naivni (u informatičkom smislu) da klikaju na takve gluposti…

 

Također…. na nekim blogovima su ljudi stavili tipa: logirajte se na svoj blog…. vi upišete username i password, i vas stvarno logira na blog… niti ne znate da ste nasamareni…. čovijek si pošalje na mail vaše podatke toliko brzo da niti ne skužite….. ovo su samo neki primjeri….

 

pamet u glavu!

 

credits Jazzfan

 

 

 

4 thoughts on “Sigurni php kod

Leave a Reply

Your email address will not be published. Required fields are marked *