Securizarea formularelor

Ai o întrebare legată de PHP? Incercăm să îi găsim soluţie. Sau poate doar vrei să publici un cod interesant.

Moderatori: Zamolxe, Moderatori

Avatar utilizator
cvlan
Average Member
Mesaje: 94
Membru din: Dum Ian 11, 2009 9:13 pm
Localitate: Fetesti
Contact:

Securizarea formularelor

Mesajde cvlan » Mie Iun 29, 2011 9:06 pm

Scriptul de mai jos este destul de puternic pentru un formular ( caracterele speciale pot cauza probleme, se pot trimite date automat ...)

Imi puteti spune daca am omis ceva ? Sunt functii mai rapide si mai bune decat acestea ? Avetii si alte ideii mai bune pentru securitate ?

Datele din formular sau din url pot afecta si conditiile de genul if(strlen($_POST['name']) < 1 OR strlen($_GET['name'])){ .... }
sau produc erori doar la db ?

<?php

session_start();

$a = "asd@sa dssd adsa$dfd32ssa";

function id(){
global $a;
$b = sha1(uniqid ($a . mt_rand(0, 9) . $a . mt_rand(0, 9) . $a, true));
$_SESSION['id'] = $b;
return $b;
}

if(isset($_POST) AND $_POST['id'] === $_SESSION['id']){

$_POST = array_map("strip_tags", $_POST);
$_POST = array_map("trim", $_POST);

if(strlen($_POST['name']) < 2 OR strlen($_POST['name']) > 20){
$error = "Numele trebuie sa contina minim 2 caractere si maxim 20.";
}elseif(strlen($_POST['prenume']) < 2 OR strlen($_POST['prenume']) > 20){
$error = "Prenumele trebuie sa contina minim 2 caractere si maxim 20.";
}else{
$nume = mysql_real_escape_string($_POST['nume']);
$prenume = mysql_real_escape_string($_POST['prenume']);
//urmeaza adaugarea datelor in db
}}



Este bun scriptul de mai jos pentru a verifica daca este un domeniu sau o pagina de domeniu si nu altceva ?

if(preg_match("/^https?:\/\/(www.)?[a-zA-Z0-9]([a-zA-Z0-9-]?)+[a-zA-Z0-9]\.(ro|com|net|info|org)(\/[a-zA-Z0-9\.\/%&=\?\-_[\]]*)*$/i", $_POST['link']) != 1){
echo "Adresa url trebuie sa fie de forma http://www.domeniu.ro / http://domeniu.ro / http://www.domeniu.ro /pag ....";
}

Multumes!


-

w3apps
Average Member
Mesaje: 156
Membru din: Joi Sep 02, 2010 11:41 pm

Mesajde w3apps » Joi Iun 30, 2011 2:54 am

Salut,

Treaba asa cu SQL INJECTION si BLIND SQL INJ ... este cam supraestimata.
Este adevarat ca poate provoca pagube imense in functie de situatie, insa dupa parerea mea este destul de usor de prevenit.

Ce vrei tu sa eviti este ca din cauza unei variabile trimise in URL sa iti modifice interogarea care vrei tu sa o faci, adica:

in loc de: SELECT * FROM `personal` WHERE `nume`='ionel'
sa se execute SELECT * FROM `personal` WHERE `nume`='' || 'a'='a'
unde ' || 'a'='a este ce a ai primit in URL

Pentru a evita asa ceva trebuie sa tii cont de urmatoarele:
- o variabila din url poate fi numerica (id-uri) sau string (nume, cuvinte pentru cautari)
- pentru variabilele care te astepti sa fie numerice pui o conditie sa verifice daca este numeric, astfel un injection de genul celui de mai jos nu va trece niciodata
- pentru string-uri trebuie sa fi sigur ca faci "escape" la ghilimele si la apostrof, adica sa le pui un slash in fata "\" si din nou injection-ul de mai sus nu va trece

Eu unul cred ca ar trebui sa fii mai atent la XSS Injection decat la SQL.

Sper sa te ajute la ceva.

Avatar utilizator
cvlan
Average Member
Mesaje: 94
Membru din: Dum Ian 11, 2009 9:13 pm
Localitate: Fetesti
Contact:

Mesajde cvlan » Joi Iun 30, 2011 4:19 am

if(is_numeric($_POST['tel'])){
$tel = (int)$tel;
}else{
$tel = 0;
}

$name = mysql_real_escape_string($_POST['name']);
sau
$name = addslashes($_POST['name'])

ce functii sunt mai rapide si mai sigure pentru a anula caracterele problematice din formulare ?

ghilimerele simple, duble sau alte caractere speciale pot afecta si if(strlen($_POST['name'])){ echo $a; } sau if(preg_match("...", $_POST['name']) != 1){ echo $a; } sau alte functii / conditii incluse in if - elseif ?

Multumesc!

w3apps
Average Member
Mesaje: 156
Membru din: Joi Sep 02, 2010 11:41 pm

Mesajde w3apps » Joi Iun 30, 2011 4:34 am

Habar n-am care este buna. Eu cand folosesc, folosesc mysql_real_escape_string().

Nu iti pot afecta conditiile ca cele pe care le-ai enumeratu tu, insa ai grija cand folosesti preg_match:

if (preg_match("/?/i", "ce faci ?")) - asa ceva ti-ar return false
if (preg_match("/\?/i", "ce faci ?")) - asta e varianta corecta (mai sunt si alte caractere in afara de ? la care trebuie sa le faci escape).


Bafta!

Avatar utilizator
cvlan
Average Member
Mesaje: 94
Membru din: Dum Ian 11, 2009 9:13 pm
Localitate: Fetesti
Contact:

Mesajde cvlan » Sâm Iul 02, 2011 7:30 pm

Este suficient aceasta conditie pentru a adauga numai nr intregi in baza de date ? Are rost sa mai pun in if si $val = mysql_real_escape_string($_POST['val']); ?

if(preg_match("/^[0-9]+$/", $_POST['val']) === 1){
//INSERT INTO ..... VALUES('{ $_POST['val']}');
}

Multumesc !

w3apps
Average Member
Mesaje: 156
Membru din: Joi Sep 02, 2010 11:41 pm

Mesajde w3apps » Sâm Iul 02, 2011 7:38 pm

Salut,

Incearca sa nu folosesti atat de mult preg_match deoarece foloseste mult mai multe resurse decat functii precum:

is_int() sau is_numeric()

preg_match foloseste-l cand vrei sa faci un regexp complex nu decat sa cauzi cifre sau litere in string, exista functii mult mai bune pentru chestii asa de simple.

Cat despre adaugare is a mysql_real_escape_string() ... nu stiu ce sa zic ... nu cred ca strica sa fii putin mai sigur insa eu nu stiu vreun injection care sa treaca de is_int(). pentru ca iti valideaza doar: 1, 2, 12, 432, 54353 etc ... nici macar 2.5 nu iti valideaza asa ca ....

Avatar utilizator
cvlan
Average Member
Mesaje: 94
Membru din: Dum Ian 11, 2009 9:13 pm
Localitate: Fetesti
Contact:

Mesajde cvlan » Sâm Iul 02, 2011 7:57 pm

<input type="hidden" name="nr" value="3" />
if(is_int($_POST['nr'])){
//La aceasta conditie imi da fals. Il considera sir sau am gresit eu cu ceva ?
}

w3apps
Average Member
Mesaje: 156
Membru din: Joi Sep 02, 2010 11:41 pm

Mesajde w3apps » Sâm Iul 02, 2011 8:12 pm

Scuze, greseala mea. Din cate imi aduca aminte toate variabilele care vin prin $_REQUEST vin ca siruri de caractere. Din acest motiv ar trebui sa folosesti functia: intval()

intval("5") // returneaza 5
intval("abc") // nu returneaza nimic cred

si atunci ar trebui sa folosesti o chestie de genul if (strlen(intval($_POST['post_field'])) > 0) ..... asta daca intval("abc") nu returneaza nimic

Joaca-te putin cu intval() si vezi ce si cum.


Înapoi la “Cod PHP”

Cine este conectat

Utilizatori ce ce navighează pe acest forum: Niciun utilizator înregistrat și 15 vizitatori