 |
Forum PHP Romania - Discutii despre PHP, MySQL, Javascript, AJAX, etc Comunitatea PHP Romania
|
| Subiectul anterior :: Subiectul următor |
| Autor |
Mesaj |
alopia
Data înscrierii: 02/Sep/2007
Mesaje: 35
|
| Trimis: Lun Noi 12, 2007 6:10 pm Titlul subiectului: Securitate PHP - FAQ |
|
|
Am citit foarte multe topicuri pe acest forum legate de atacuri, securizare site etc.
M-am gindit ca un topic pe aceasta tema care sa incerce sa sintetizeze principalele slabiciuni ale unui script PHP si eventual sa ofere si solutii ar fi binevenit. Va rog de asemenea sa nu "injectati" pe cit posibil acest topic cu probleme personale punctuale.
Va rog de asemenea daca aveti alte idei sau solutii privind securitatea PHP sa le postati aici. Cu ajutorul vostru voi dezvolta acest topic pe parcurs in mai multe etape.
In primul post voi realiza o clasa pentru filtrat sursa multor probleme de securitate in PHP respectiv variabilele atribuite scriptului de catre utilizator. Voi scrie cod PHP cit mai pe intelesul tuturor.
Reguli
Voi evita prescurtarile posibile pentru IF -uri sau alte lucruri de acest tip pentru ca totul sa fie usor de inteles. Am ales arbitrar prefixul gem pentru clase dupa initialele numelui meu mai ales pentru a nu interfera cu alte clase definite de dumneavoastra. Comentariile le voi face in limba engleza pentru ca intentionez sa postez acest tutorial si pe un site de vorbitori de limba engleza si pentru ca datorita muncii in echipa m-am obisnuit sa-mi comentez codul in engleza. Toate variabilele temporare din interiorul functiilor vor primi prefixul $temp pentru a nu interfera in viitor cu alte variabile globale. Codul va trebui sa ruleze atit pe PHP 4 cit si pe PHP 5 deci teoretic codul ar trebui sa ruleze pe orice server.
Pentru inceput nu uitati asigurati-va ca register_globals este OFF. Pentru mai multe detalii despre posibilele probleme generate atunci cind register_globals este ON va rog sa consultati manualul PHP:
htttp://www.php.net/manual/en/security.globals.php
Scopul clasei de mai jos este sa fiti siguri ca atunci cind asteptati ca utilizatorul sa introduca un string, un integer sau un float de exemplu sa fiti sigur ca utilizatorul a introdus asa ceva. Ca bonus aveti o functie care poate transforma un string continind o lista cu elementele separate de un anumit caracter intr-un array (de exemplu : "email@yahoo.com|altemail@yahoo.com|email@email.com" )
De asemenea scopul clasei este sa nu va mai bateti capul privind metoda cum au fost introduse variabilele (GET, POST). Clasa va cauta singura variabila dorita, va face verificarile de rigoare si o va returna.
De asemenea clasa va permite ca in cazul in care o variabila lipseste ea sa fie inlocuita cu o valoare DEFAULT care doriti dumneavoastra.
Scriptul va functiona de asemenea si pe versiuni mai vechi de PHP unde $_POST si $_GET nu sunt definite.
Cod:
/**
* This class can be used to handle $_GET, $_POST, $HTTP_GET_VARS and $HTTP_POST_VARS arrays.
*/
class gemGP
{
/**
* Search and return the specified variable from $_GET, $_POST, $HTTP_GET_VARS or $HTTP_POST_VARS
*/
function Private_Get($pI)
{
global $HTTP_POST_VARS, $HTTP_GET_VARS;
// First of all try to use the prefered session method
// ( check SID to detect session method )
if ( defined('SID') )
{
if ( isset($_GET[$pI]) ) return trim($_GET[$pI]);
if ( isset($HTTP_GET_VARS[$pI]) ) return trim($HTTP_GET_VARS[$pI]);
} else
{
if ( isset($_POST[$pI]) ) return trim($_POST[$pI]);
if ( isset($HTTP_POST_VARS[$pI]) ) return trim($HTTP_POST_VARS[$pI]);
}
// No match ! Try to guess now ...
// Generaly we wont reach this point if the session method detection was succesfuly
// and the variable exists ...
if ( isset($_POST[$pI]) ) return trim($_POST[$pI]);
if ( isset($HTTP_POST_VARS[$pI]) ) return trim($HTTP_POST_VARS[$pI]);
if ( isset($_GET[$pI]) ) return trim($_GET[$pI]);
if ( isset($HTTP_GET_VARS[$pI]) ) return trim($HTTP_GET_VARS[$pI]);
// Nothing ...
return false;
}
/** Search and return the specified variable even from $_GET, $_POST, $HTTP_GET_VARS or $HTTP_POST_VARS
*/
function Get($pI)
{
$tempVar = gemGP::Private_Get($pI);
if ( is_string($tempVar) )
{
if (get_magic_quotes_gpc())
{
$tempVar = stripslashes($tempVar);
}
}
return $tempVar;
}
/**
* Always returns a boolean variable (0 or 1)
*/
function AlwaysGet_Boolean($pV,$pDefault)
{
$pV = gemGP::Get($pV);
if (is_string($pV))
{
$tempVal = intval($pV);
if ( ( is_numeric($pV) ? $tempVal == $pV : false ) )
{
if ($tempVal == 0) return 0;
return 1;
}
}
return $pDefault;
}
/**
* Always returns a integer variable
*/
function AlwaysGet_Integer($pV,$pDefault,$pLegalValues=NULL,$pLVR=false)
{
$pV = gemGP::Get($pV);
if ( is_string($pV) )
{
$tempVal = intval($pV);
if ( ( is_numeric($pV) ? $tempVal == $pV : false ) )
{
if ( isset($pLegalValues) )
{
if ( $pLVR )
{
if ( $tempVal >= $pLegalValues['min'] && $tempVal <= $pLegalValues['max'] ) return $tempVal;
} else
{
foreach($pLegalValues as $tempLV)
{
if ( $tempLV == $tempVal ) return $tempLV;
}
}
return $pDefault;
}
return $tempVal;
}
}
return $pDefault;
}
/**
* Always returns a float variable
*/
function AlwaysGet_Float($pV,$pDefault,$pLegalValues=NULL,$pLVR=false)
{
$pV = gemGP::Get($pV);
if ( is_string($pV) )
{
$pV = str_replace(',','.',$pV);
$tempVal = floatval($pV);
if ( ( is_numeric($pV) ? $tempVal == $pV : false ) )
{
if ( isset($pLegalValues) )
{
if ( $pLVR )
{
if ( $tempVal >= $pLegalValues['min'] && $tempVal <= $pLegalValues['max'] ) return $tempVal;
} else
{
foreach($pLegalValues as $tempLV)
{
if ( $tempLV == $tempVal ) return $tempLV;
}
}
return $pDefault;
}
return $tempVal;
}
}
return $pDefault;
}
/**
* Always returns a string variable
*/
function AlwaysGet_String($pV,$pDefault)
{
$pV = gemGP::Get($pV);
if ( is_string($pV) ) return $pV;
return $pDefault;
}
/**
* Always return an word array. Word arrays are arrays created from strings where words are separated by a special character (default is comma).
*/
function AlwaysGet_Wordarray($pV,$pDefault,$pSep=',')
{
$pV = gemGP::Get($pV);
if (is_string($pV))
{
$pV = explode($pSep, $pV);
$tempA = array();
foreach($pV as $tempS)
{
$tempS = trim($tempS);
if ( strlen($tempS) > 0 ) $tempA[] = $tempS;
}
return $tempA;
}
return $pDefault;
}
}
In urmatorul post voi veni cu o clasa care se va ocupa cu conectarea la baza de date mysql si filtrarea query-urilor pentru a nu permite injectarea comenzilor catre baza de date.
Dupa terminarea acestor doua clase va urma o clasa bazata pe ele care se va ocupa de securitatea unei sesiuni PHP unde voi discuta pe larg toate problemele de securitatea si modul in care le putem rezolva.
|
|
| Sus |
|
Pirahna
Data înscrierii: 22/Aug/2004
Mesaje: 4339
Locație: la birou
|
| Trimis: Lun Noi 12, 2007 6:19 pm Titlul subiectului: |
|
|
| mie nu mi se pare ca asta ar trebui sa fie la php avansat |
|
| Sus |
|
alopia
Data înscrierii: 02/Sep/2007
Mesaje: 35
|
| Trimis: Lun Noi 12, 2007 6:26 pm Titlul subiectului: |
|
|
| Da ai dreptate. Daca poate un moderator muta la incepatori ar fi OK. Nu m-am gindit la chestia asta cind am postat. |
|
| Sus |
|
dechim
Data înscrierii: 10/Mai/2005
Mesaje: 532
Locație: Drobeta Turnu Severin
|
| Trimis: Lun Noi 12, 2007 7:09 pm Titlul subiectului: |
|
|
Ce zici de o clasa care sa stearga fisierele aparute in subfolderele unei aplicatii cu exceptia celor dintr-un folder (sau mai multe) pentru upload.
Cineva spunea saptamana trecuta, pe acest forum, ca-i apar fisiere chiar in radacina aplicatiei.
Eu zic ca nu-i o problema personala.
Ma gandesc sa diferentieze fisierele aplicatiei de cele intruse prin compararea cu o lista pe care scriptul sa si-o faca la cerere (la instalarea aplicatiei, la upgrade,..) intr-un fisier.
Actiunea de curatare sa se faca la fiecare accesare a fisierului index sau la logarea unui utilizator sau de catre un script care se executa repede si ne permitem sa-i marim timpul de raspuns prin realizarea in plus a acestei actiuni.
Cred ca-i si extrem de periculos, risti sa stergi aplicatia.
Poate este suficient sa anunte admin-ul cand apar fisiere noi si sa ia el o decizie.
Nu stiu daca am fost foarte explicit!
Tutoriale care trateaza problema securitatii sunt multe pe net, exemplu: http://www.siteuri.ro/developer/ghidul-securitatii-php.php |
|
| Sus |
|
arhimede
Data înscrierii: 05/Dec/2005
Mesaje: 13
|
| Trimis: Mar Noi 13, 2007 3:19 am Titlul subiectului: |
|
|
sincer, nu inteleg care este rostul clasei de mai sus. perpetueaza cod antic si incurajeaza folosirea in continuare a php4.
simplu extensia filter: http://php.net/filter si gata, cu un singur rind de cod ai curatat/validat orice input. |
|
| Sus |
|
PHPRomania Bot
Bot Member
Data înscrierii: 27/Dec/2007
Mesaje: 1
Locaţie: Server Google |
| Trimis: Mie Dec 26, 2007 7:01 pm Titlul subiectului: Ad |
|
|
|
|
|
| Sus |
|
| |
|