2009-11-28 3 views
2

Un script « go » qui va chercher tout autre scénario demandé et c'est ce que je l'ai écrit pour aseptiser l'entrée utilisateur:PHP/MYSQL: Désinfecter l'entrée de l'utilisateur - est-ce une mauvaise idée? Je

foreach ($_REQUEST as $key => $value){ 
    if (get_magic_quotes_gpc()) 
    $_REQUEST[$key] = mysql_real_escape_string(stripslashes($value)); 
    else 
    $_REQUEST[$key] = mysql_real_escape_string($value); 
} 

Je ne l'ai pas vu quelqu'un d'autre utilisation de cette approche. Y a-t-il une raison de ne pas le faire?

EDIT - modifié pour travailler pour les tableaux:

function mysql_escape($thing) { 
    if (is_array($thing)) { 
    $escaped = array(); 
    foreach ($thing as $key => $value) { 
     $escaped[$key] = mysql_escape($value); 
    }   
    return $escaped; 
    } 
    // else 
    if (get_magic_quotes_gpc()) $thing = stripslashes($thing); 
    return mysql_real_escape_string($thing); 
} 

foreach ($_REQUEST as $key => $value){ 
    $_REQUEST[$key] = mysql_escape($value); 
} 

Répondre

9

je trouve beaucoup mieux pour échapper aux données au moment où il est utilisé, et non sur la manière Vous pouvez utiliser ces données dans. JSON, XML, Shell, MySQL, Curl ou HTML et chacun aura sa propre façon d'échapper les données.


Permet d'avoir un examen rapide Pourquoi des caractères est nécessaire dans des contextes différents:

Si vous êtes dans une chaîne délimitée par citation, vous devez être en mesure d'échapper aux citations. Si vous êtes en XML, alors vous devez séparer "contenu" de "balisage" Si vous êtes en SQL, vous devez séparer les "commandes" de "données" Si vous êtes sur la ligne de commande, vous devez séparer "commands" from "data"

C'est un aspect vraiment fondamental de l'informatique en général. Parce que la syntaxe qui délimite les données peut se produire dans les données, il doit y avoir un moyen de différencier les données de la SYNTAX, par conséquent, l'échappement.

Dans la programmation web, les cas les plus courants fuyants sont: 1. texte Émission en HTML 2. Les données de la sortie dans les attributs HTML 3. Produire du HTML en HTML 4. Les données à insérer dans Javascript 5. Données de l'insertion dans SQL 6. Insertion de données dans une commande shell

Chacune a des implications de sécurité différentes si elle n'est pas gérée correctement. C'est vraiment important! Passons en revue dans le contexte de PHP:

  1. Texte en HTML: htmlspecialchars (...)

  2. données dans les attributs HTML htmlspecialchars (..., ENT_QUOTES)

  3. HTML en HTML Utilisez une bibliothèque telle que HTMLPurifier pour vous assurer que seules les balises valides sont présentes.

  4. Données en Javascript Je préfère json_encode. Si vous le placez dans un attribut, vous devez toujours utiliser # 2, tel que

  5. Insertion de données dans SQL Chaque pilote possède une fonction escape() quelconque. C'est mieux. Si vous utilisez un jeu de caractères latin1 normal, addslashes (...) est approprié. N'oubliez pas les guillemets AUTOUR de l'appel addslashes():

    "INSERT INTO table1 SET field1 = '". addslashes ($ data)."'"

  6. données sur la ligne de commande escapeshellarg() et escapeshellcmd() - lire le manuel

- Prenez-les à cœur, et vous permettra d'éliminer 95% * de commun risques de sécurité Web! (* une supposition)

+0

Malheureusement, mon jeu de caractères est UTF-8 et ne se limite pas à des caractères latins. Je l'ai descendu pour que tout soit échappé correctement, mais je suppose que je suis juste trop paranoïaque que je vais laisser quelque chose ouvert d'injection SQL. – Greg

+0

mysql_real_escape_characters est la meilleure option pour désinfecter les entrées utilisateur qui vont dans la base de données. – Residuum

+0

@Residuum: Je n'arrive pas à trouver ça dans le manuel. – Greg

2

Votre approche essaye de désinfecter toutes les données de demande pour l'insertion dans la base de données, mais que se passe-t-il si vous avez juste voulu le produire? Vous aurez des barres obliques inverses inutiles dans votre sortie. En outre, l'échappement n'est pas une bonne stratégie pour se protéger des exceptions SQL de toute façon. En utilisant des requêtes paramétrées (par exemple dans PDO ou dans MySQLi), vous "passez" le problème de l'échappement à la couche d'abstraction.

3

Si vous avez des tableaux dans votre $_REQUEST, leurs valeurs ne seront pas nettoyées.

+1

+ 1 pour accord. Une désinfection récursive est requise. – mauris

+0

Merci d'avoir signalé cela. J'ai édité ma question. – Greg

2

Outre l'absence de récursivité dans les tableaux et l'échappement inutile de nombres entiers, par exemple, cette approche code les données à utiliser dans une instruction SQL avant la désinfection. mysql_real_escape_string() échappe des données, il ne le désinfecte pas - s'échapper et désinfecter ne sont pas la même chose.

La désinfection est la tâche que de nombreux scripts PHP ont de scruter les données d'entrée pour leur acceptabilité avant de l'utiliser. Je pense que cela est mieux fait sur des données qui n'ont pas été échappées. En général, je n'échappe pas aux données avant d'entrer dans le SQL. Ceux qui préfèrent utiliser Prepared Statements obtiennent la même chose.

Encore une chose: Si les données d'entrée peuvent inclure des chaînes utf8, il semble qu'elles doivent être validées avant de s'échapper. J'utilise souvent un nettoyeur récursif utf8 sur $ _POST avant la désinfection.

3

Je l'ai fait et d'utiliser celui-ci:

<?php 
function _clean($var){ 
    $pattern = array("/0x27/","/%0a/","/%0A/","/%0d/","/%0D/","/0x3a/", 
        "/union/i","/concat/i","/delete/i","/truncate/i","/alter/i","/information_schema/i", 
        "/unhex/i","/load_file/i","/outfile/i","/0xbf27/"); 
    $value = addslashes(preg_replace($pattern, "", $var)); 
    return $value; 
} 

if(isset($_GET)){ 
    foreach($_GET as $k => $v){ 
     $_GET[$k] = _clean($v); 
    } 
} 

if(isset($_POST)){ 
    foreach($_POST as $k => $v){ 
     $_POST[$k] = _clean($v); 
    } 
} 
?> 
Questions connexes