2010-11-19 26 views
50

Ho un sacco di input dell'utente da $_GET e $_POST ... Al momento scrivo sempre mysql_real_escape_string($_GET['var']) ..L'ultimo pulita funzione/secure

Vorrei sapere se si potrebbe fare una funzione che protegge, fugge e pulisce subito gli array $_GET/$_POST, quindi non dovrai occupartene ogni volta che lavori con gli input dell'utente e così via.

Stavo pensando di una funzione, per esempio cleanMe($input), e al suo interno, che dovrebbe fare mysql_real_escape_string, htmlspecialchars, strip_tags, stripslashes (penso che sarebbe tutto per rendere pulito & sicuro) e poi restituire il $input.

Quindi è possibile? Fare una funzione che funziona per tutti $_GET e $_POST, così si dovrebbe fare solo questo:

$_GET = cleanMe($_GET); 
$_POST = cleanMe($_POST); 

Quindi nel tuo codice in seguito, quando si lavora con per esempio $_GET['blabla'] o $_POST['haha'], essi sono garantiti, spogliati e così via?

me provato un po ':

function cleanMe($input) { 
    $input = mysql_real_escape_string($input); 
    $input = htmlspecialchars($input, ENT_IGNORE, 'utf-8'); 
    $input = strip_tags($input); 
    $input = stripslashes($input); 
    return $input; 
} 
+50

'stripslashes()' * dopo * 'mysql_real_escape_string()' ... i miei eyeees! – jensgram

+0

Penso che la sicurezza dei dati dipenda da ciò che fanno e da dove provengono. Tutti i tuoi trattamenti non sono necessariamente necessari. – MatTheCat

+13

L'utilizzo di una funzione di sterilizzazione master monouso non è la soluzione giusta. Ecco perché [citazioni magiche] (http://php.net/manual/en/security.magicquotes.php) non è riuscito. Fuga (o usare soluzioni migliori come le dichiarazioni preparate) * se e quando * ne hai bisogno. Altrimenti, scoprirai di scappare nei momenti sbagliati, e spesso più di una volta. Tutte queste funzioni hanno scopi molto diversi, e diverse (ad esempio 'mysql_real_escape_string' e' stripslashes') sono essenzialmente inverse. Vedi [Qual è il miglior metodo per sanitizzare l'input dell'utente con PHP? ] (http: // stackoverflow.it/questions/129677) per maggiori informazioni. –

risposta

117

L'idea di una funzione di servizi igienico-sanitari generica è un concetto rotto.

C'è uno metodo di sanificazione giusto per ogni scopo. Eseguirli tutti indiscriminatamente su una stringa spesso li romperà: l'escape di un pezzo di codice HTML per una query SQL lo interromperà per l'uso in una pagina Web e viceversa. Servizi igienico-sanitari deve essere applicato destra prima utilizzando i dati:

  • prima di eseguire una query di database. Il giusto metodo igienico-sanitario dipende dalla libreria che usi; appaiono nella How can I prevent SQL injection in PHP?

  • htmlspecialchars() per l'output HTML sicuro

  • preg_quote() per l'uso in un'espressione regolare

  • escapeshellarg()/escapeshellcmd() per l'uso in un comando esterno

  • etc. etc.

Usare una funzione di sanificazione "taglia unica" è come utilizzare cinque tipi di insetticidi altamente tossici su una pianta che, per definizione, può contenere solo un tipo di insetto, solo per scoprire che le tue piante sono infestate da un sesto tipo, che nessuno degli insetticidi funziona.

Utilizzare sempre il metodo giusto, idealmente dritto prima di passare i dati alla funzione. Mai metodi di miscelazione a meno che non sia necessario.

+48

Abbiamo passato "servizi igienici automatizzati" con magic_quotes. Mai più. – Mchl

+3

@Mchl +1 Questo è probabilmente il motivo numero uno * * per l'insicurezza nelle soluzioni PHP. Fondamentalmente ha incoraggiato l'ignoranza del programmatore :) – jensgram

+4

Vorrei aggiungere che vale la pena considerare l'utilizzo di istruzioni preparate (PDO o mysqli) invece per le query del database. –

7

Non è necessario passare semplicemente l'input attraverso tutte queste funzioni. Tutte queste funzioni hanno significati diversi. I dati non diventano "più puliti" chiamando più funzioni di escape.

Se si desidera memorizzare l'input dell'utente in MySQL è necessario utilizzare solo mysql_real_escape_string. Viene quindi completamente salvato per l'archiviazione sicura nel database.

EDIT

noti inoltre i problemi che sorgono con utilizzando le altre funzioni. Se il client invia per esempio un nome utente al server e il nome utente contiene una e commerciale (&), non si desidera aver chiamato htmlentities prima di memorizzarlo nel database perché il nome utente nel database conterrà &.

1

Posso suggerire di installare "mod_security" se si utilizza apache e si ha accesso completo al server ?!
Ha risolto la maggior parte dei miei problemi. Tuttavia non fare affidamento solo su una o due soluzioni, scrivere sempre codice sicuro;)
UPDATE Trovato questo ID PHP (http://php-ids.org/); sembra bello :)

+0

Che cosa ha a che fare mod_security con l'escaping di input, l'iniezione SQL, ecc.? – BoltClock

+0

@BoltClock Vedere la sezione Regole di configurazione comunemente utilizzate in [questo articolo] (http://www.thebitsource.com/infrastructure-operations/web-application/securing-apache-web-servers-modsecurity/), o vedere un altro uno di Symantec: [Web Security Appliance con Apache e mod_security] (http://www.symantec.com/connect/articles/web-security-appliance-apache-and-modsecurity). –

+0

@BoltClock: è come una guardia del corpo, anche quando si incasina, è lì per aiutarti;) –

6

Stai cercando filter_input_array(). Tuttavia, suggerisco di utilizzarlo solo per la convalida/sanificazione in stile business e non per il filtraggio degli input SQL.

Per la protezione contro l'iniezione SQL, utilizzare query parametrizzate con mysqli o PDO.

3

Il problema è, qualcosa di pulito o sicuro per un uso, non sarà per un altro: pulizia per parte di un percorso, per parte di una query mysql, per output html (come html, o in javascript o in un valore di input), per xml può richiedere cose diverse che contraddicono.

Ma alcune cose globali possono essere fatte. Prova a usare filter_input per ottenere l'input dell'utente. E usa prepared statements per le tue query SQL.

Sebbene, invece di una funzione fai-da-tutto, è possibile creare una classe che gestisce i propri input. Qualcosa del genere:

class inputManager{ 
    static function toHTML($field){ 
    $data = filter_input(INPUT_GET, $field, FILTER_SANITIZE_SPECIAL_CHARS); 
    return $data; 
    } 
    static function toSQL($field, $dbType = 'mysql'){ 
    $data = filter_input(INPUT_GET, $field); 
    if($dbType == 'mysql'){ 
     return mysql_real_escape_string($data); 
    } 
    } 
} 

Con questo tipo di cose, se si vede alcuna $ _POST, $ GET, $ o $ _REQUEST _COOKIE nel codice, sai che devi cambiarlo. E se un giorno dovessi cambiare il modo in cui filtri i tuoi input, cambia semplicemente la classe che hai creato.

-1

ho usato tale matrice passaggio o GET, POST

function cleanme(&$array) 
{ 
if (isset($array)) 
{ 
    foreach ($array as $key => $value) 
    { 
      if (is_array($array[$key])) 
      { 
      secure_array($array[$key]); 
      } 
      else 
      { 
      $array[$key] = strip_tags(mysql_real_escape_string(trim($array[$key]))); 
      } 
    } 
} 
} 

Usage:

cleanme($_GET); 
cleanme($_POST); 
+0

quale sarà il tipo di ritorno di questo array –

+0

viene passato per riferimento in modo che la sua modifica direttamente, nessun ritorno di dati, si aggiorni risposta. – user889030

0
<?php 
function sanitizeString($var) 
{ 
    $var = stripslashes($var); 
    $var = strip_tags($var); 
    $var = htmlentities($var); 
    return $var; 
} 

function sanitizeMySQL($connection, $var) 
{ 
    $var = $connection->real_escape_string($var); 
    $var = sanitizeString($var); 
    return $var; 
} 
?> 
Problemi correlati