Pagina de start a forumului Forum PHP Romania - Discutii despre PHP, MySQL, Javascript, AJAX, etc Forum PHP Romania - Discutii despre PHP, MySQL, Javascript, AJAX, etc
Comunitatea PHP Romania
 

Securitate PHP - FAQ
Vezi mesajul original

 
       Pagina de start a forumului Forum PHP Romania - Discutii despre PHP, MySQL, Javascript, AJAX, etc -> PHP Avansat
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  
 
       Pagina de start a forumului Forum PHP Romania - Discutii despre PHP, MySQL, Javascript, AJAX, etc -> PHP Avansat
Pagina 1 din 1


Powered by phpBB 2.0.22 © 2001, 2002 phpBB Group
Varianta în limba română: Romanian phpBB online community