· Ok, ai scris o aplicaţie web. Eşti 99% sigur că e impenetrabilă?
· Când începi să scrii o aplicaţie web, te gândeşti de la început la partea de securitate?
· E o joacă de copii să adaugi partea de securitate la o aplicaţie existentă?

Dacă ai răspuns nu la toate întrebările atunci merită să citeşti acest articol. Nu e nici un secret că mulţi programatori dau atenţie securităţii abia în ultima parte a proiectului, atunci când nu există prea mult timp pentru aşa ceva.

În continuare vreau să ofer o soluţie elegantă pentru filtrarea datelor venite de la utilizator, şi anume, separarea codului ce ţine de securitate, de restul aplicaţiei. Astfel, soluţia poate fi adoptată cu aceeaşi uşurinţă atât pentru proiectele noi, cât şi pentru cele deja existente. Articolul este scris relativ la PHP, dar cred că aceleaşi principii sunt valabile şi pentru ASP, JSP şi alte limbaje.

Am să încep cu nişte exemple. Nu de puţine ori am văzut cod de genul
[code lang="php"]mysql_query("select * from products where id=" . (int)$_GET["product_id"]);[/code]
sau
[code lang="php"]mysql_query("select * from users where username='" . addslashes($_POST["user"] . "' and pass...");[/code]
sau
[code lang="php"]echo strip_tags($_POST["comment"]);[/code]
Acest mod de a asigura securitatea este foarte greoi şi îţi oferă numeroase „şanse” să greşeşti. Pentru mulţi programatori e un chin.

Ce bine ar fi să poţi scrie liniştit [code lang="php"]mysql_query("select * from users where username='$_POST[user]' and pass...");[/code] Ei bine, se poate, fară a face rabat pe partea de securitate!

Ideea de bază constă în verificarea tuturor variabilelor din GET, POST şi COOKIE înainte de a ajunge (de a fi folosite) în aplicaţia propriu-zisă. Cel mai simplu* mod pentru a face asta, este de a scrie o funcţie pentru fiecare variabilă ce trebuie verificată.

[code lang="php"]
//pentru exemplul de mai sus in care avem $_POST["user"], functia de verificare
//ar putea arata in felul urmator:

function check_POST_user($value){
  if (!eregi("^[a-z0-9]$", $value){
    die('user: valoare nepermisa');
  }
}

//aici vin scrise functii pentru restul variabilelor

//apelarea functiilor pentru fiecare variabila se face astfel:
foreach ($_POST as $var => $value){
  $function_name = "check_POST_" . $var;
  if (!function_exists($function_name)){
    die("scrie functie pentru a verifica _POST[$var]");
  }
  $function_name($value);
}
[/code]

Pentru simplitate, am dat un exemplu minimal de programare procedurală, dar ideea se poate extinde foarte frumos folosind clase şi obiecte.

Folosesc această metodă de vreo 4 ani şi pot să spun că mi-a adus multe beneficii şi m-a eliberat de o grămadă de stres. În încheiere, vreau să subliniez câteva avantaje ale acestei metode:

  • codului aplicaţiei devine mai simplu
  • ai o privire de ansamblu: tot ce ţine de securitate se găseşte într-un loc bine stabilit
  • poţi să ştii în orice clipă care variabile sunt verificate şi care nu
  • se pretează bine la lucrul în echipă; poţi să pui un specialist să scrie funcţiile de verificare

Programare plăcută!

* Voi prezenta o modalitate şi mai simplă într-un articol viitor :P