Jump to content
B7ackAnge7z

Metodă alternativă de protecție MySQL injection

Recommended Posts

Posted

Inspirat de Dan Kaminsky, vreau s? v? prezint o metod? eficient?, simpl? ?i sigur? de protejarea aplica?iilor web împotriva vulnerabilit??ilor de tip MySQL injection. Tot de ce ave?i nevoie, este s? folosi?i urm?torul fragment de cod:

array_walk_recursive($_GET, function (&$val, $key) {
if (!is_numeric($val)) {
$val = '0x' . bin2hex($val);
}
});

Dup? care, pute?i folosi orice variabil? din masivul $_GET f?r? a v? gândi la securizarea acesteia. De exemplu, urm?toarea instruc?iune SQL este complet sigur? ?i nu are nici o importan?? ce date con?ine variabila $_GET['name']:

$sql = "SELECT * FROM users WHERE name={$_GET['name']}";

Spre deosebire de metoda lui Dan Kaminsky, în cazul dat, performan?a bazei de date nu va avea de suferit, iar ceea ce prive?te PHP — func?ia bin2hex() e mai rapid? chiar ?i ca mysqli_escape_string() — astfel, la capitolul performan??, totul e minunat.

Totu?i, în dependen?? de aplica?ie ?i cerin?ele ei, vei fi nevoit s? schimbi corespunz?tor fragmentul de cod ar?tat mai sus. Cel mai corect ar fi ca s? creezi o nou? variabil? unde s? p?strezi datele ce le vei folosi la crearea interog?rilor SQL. De exemplu, putem crea urm?toarea func?ie:

function hex_secure($vars)
{
array_walk_recursive($vars, function (&$val, $key) {
if (!is_numeric($val)) {
$val = '0x' . bin2hex($val);
}
});

return $vars;
}

?i o folosim în modul urm?tor:

$vars = hex_secure($_GET);
$sql = "SELECT * FROM users WHERE name={$vars['name']}";

Posted

El a inventat treaba asta? Ma indoiesc. E doar o metoda de patching in bloc a unor date. Nothing fancy. In practica, metodele de genul nu sunt bune pentru ca ai foarte multe exceptii. :-)

Posted
El a inventat treaba asta? Ma indoiesc. E doar o metoda de patching in bloc a unor date. Nothing fancy. In practica, metodele de genul nu sunt bune pentru ca ai foarte multe exceptii. :-)

Nu sunt 100% sigur, dar se pare c? chestia cu Base64 este idea lui (cel pu?in mul?i au fost impresiona?i).

Cât despre practic?, vezi urm?torul request:

ajax.filter.php?price[min]=350&price[max]=500&vendors[]=HP&vendors[]=IBM&vendors[]=Acer&ram[timing][]=DDR2&ram[timing][]=DDR3&ram[size][min]=2048&&ram[size][max]=9000&[...+20 de variabile]

Cred, c? metoda ar?tat? de mine, simplific? cu mult codul aplica?iei pentru astfel de situa?ii.

ps. Dac? po?i, te-a? ruga în 2-3 cuvinte s? explici la ce „excep?ii” de referi.

Posted

Un exemplu ar fi un camp ce suporta si altceva in afara de valori usor de interpretat(alfanumerice). Nu e usor sa procesezi un camp ce accepta taguri html(spre ex) ce mai au nevoie si de post-procesare (dupa submit). Plus ca o varianta de genul o poti integra doar intr-o solutie inhouse unde stii cum merge tot. Intr-un CMS gen Wp sau Joomla unde da, ai nevoie de protectie mai ales atunci cand vorbim de pluginuri scrise prost, nu m-as aventura. Oricum, usureaza mult, dar trebuie facut cu cap, nu generalizat. Plus ca te scapa doar de o buba, nu de toate. :-)

Posted (edited)

@Gecko,

Da-da, chestia aceasta nu e nou? (cineva prin 2008 spunea despre ea). Problema este c? stochezi datele codificate ?i astfel ocup? mai mut spa?iu + î?i creeaz? o mul?ime de probleme la toate capitolele.

Edited by B7ackAnge7z
Posted

Nu e chiar inventata, eu personal o folosesc de ani de zile in unele cazuri. Dar mananca spatiu in baza de date, este ok pentru lucruri unde nu ai nevoie de viteza, baza de date mica etc. La fel se pot pune adresele de IPv4 convertite numeric si multe alte trickuri.

Problema cu datele bagate altfel decat normal in bazele de date este ca nu poti folosi ulterior foarte simplu pentru conditii... Cauta tu rapid dupa un utilizator care il cheama %mihai%, s-ar putea sa iti apara si alte nume pentru bin2hex mihai da un string care poate sa apara si la alte nume etc. Personal bag preg_replace pe variabile in general, cel mai sigur mod de a le curata.

Posted
Nu e chiar inventata, eu personal o folosesc de ani de zile in unele cazuri. Dar mananca spatiu in baza de date, este ok pentru lucruri unde nu ai nevoie de viteza, baza de date mica etc. La fel se pot pune adresele de IPv4 convertite numeric si multe alte trickuri.

Problema cu datele bagate altfel decat normal in bazele de date este ca nu poti folosi ulterior foarte simplu pentru conditii... Cauta tu rapid dupa un utilizator care il cheama %mihai%, s-ar putea sa iti apara si alte nume pentru bin2hex mihai da un string care poate sa apara si la alte nume etc. Personal bag preg_replace pe variabile in general, cel mai sigur mod de a le curata.

Ceea ce folose?ti tu, e exact metoda descris? de @Gecko (?i da, el demult a scris despre asta). Se pare c? tu nu ai în?eles cum func?ioneaz? metoda ?i nici m?car nu ai citit atent (doar am scris c? nu sunt probleme cu performan?a). De exemplu, pentru urm?torul request:

GET /user.php?name=Mihai HTTP/1.1
Host: localhost
Accept: */*

În fi?ierul user.php avem urm?torul cod:

$_GET['name_like'] = "%{$_GET['name']}%";
$vars = hex_secure($_GET);

$insert_sql = "INSERT INTO users (name) VALUES({$vars['name']})";
$select_sql = "SELECT * FROM users WHERE name LIKE {$vars['name_like']}";

Astfel, variabila $insert_sql con?ine:

INSERT INTO users (name) VALUES(0x4d69686169)

Dar în baza de date, numele va fi stocat ca "Mihai".

Ce ?ine despre variabila $select_sql, va avea valoarea:

SELECT * FROM users WHERE name LIKE 0x254d6968616925

Îns? va returna exact acela?i r?spuns ca ?i pentru:

SELECT * FROM users WHERE name LIKE '%Mihai%'

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...