2010-08-25 8 views
5

Je récupère actuellement d'une attaque XSS désagréable, et j'ai réalisé que je n'ai jamais nettoyé les entrées sur plusieurs des formulaires mon site. J'ai utilisé la fonction Find In Files de Notepad ++ pour rechercher $_POST dans tous mes fichiers PHP, et j'ai obtenu presque 5 000 résultats. Maintenant, je ne veux vraiment pas aller ajouter manuellement strip_tags à chacun de ces résultats, mais un remplacement-tout ne ferait pas l'affaire ... et je suis un noob total quand il s'agit de choses comme des expressions régulières .

Y at-il un moyen de rendre cela un peu moins fastidieux?

Répondre

2

vous pouvez mettre ceci dans un fichier (par exemple safe.php)

foreach ($_POST as $key => $value) { 
    $_POST[$key] = is_array($key) ? $_POST[$key]: strip_tags($_POST[$key]); 
} 

ensuite mis require_once("safe.php"); dans tous les chacun de vos fichiers php (ou un fichier que l'ensemble de votre fichier php déjà inclus)
Il est un hack laid .. mais il peut gagner votre temps.

+0

Génial.Ceci est exactement ce que je cherchais. –

+0

Ceci ne protégera pas de XSS quand il y a des champs de formulaire avec des noms comme 'foo [bar]' ou 'foo []' que PHP convertit automatiquement en tableaux. – Tgr

+0

@Tgr: Oui, cela échouera absolument comme vous l'avez dit, mais je pense qu'il a eu l'idée de personnaliser en fonction de ce dont il a besoin – w00d

6

Hmm, je pense que array_walk_recursive ferait l'affaire:

function custom_strip(&$val, $index) { 
    $val = strip_tags($val); 
} 
array_walk_recursive($_POST, 'custom_strip'); 
0

Très simple. Mettre cela sur le dessus de votre chaque fichier ou dans un fichier d'en-tête commune qui est appelé dans le début à chaque fois:

function mystriptag(&$item) 
{ 
    $item = strip_tags($item); 
} 

array_walk($_POST, mystriptag); 
+0

Cela va échouer à protéger de XSS quand il y a des champs de formulaire avec des noms comme foo [bar] ' ou 'foo []' que PHP convertit automatiquement en tableaux. – Tgr

18

utiliser juste array_map().

$Clean = array_map('strip_tags', $_POST); 

Ou si vous le voulez pour revenir à la $_POST variable:

$_POST = array_map('strip_tags', $_POST); 

Il est probablement une meilleure idée que d'utiliser une variable différente et changer tout occurrence de $_POST à $Clean dans vos fichiers.

0

Vous pourriez juste array_mapstrip_tags-$_POST, mais il est beaucoup plus agréable d'écrire une fonction personnalisée pour obtenir des données de celui-ci:

function post_data($name) { 
    global $post_cache; 
    if (in_array($name, $post_cache)) { 
     return $post_cache[$name]; 
    } 
    $val = $_POST[$name]; 
    if (is_string($val)) { 
     $val = strip_tags($val); 
    } else if (is_array($val)) { 
     $val = array_map('strip_tags', $val); 
    } 
    $post_cache[$name] = $val; 
    return $val; 
} 

Cela rendra votre code plus lisible (autres qui cherchent en elle assumeront généralement que $_POST['foo'] est les données dans le champ de formulaire foo, pas quelque chose que vous avez déjà prétraité), ne vous causera pas de problèmes avec les plugins ou les bibliothèques qui tentent d'accéder $ _POST directement, il est facile d'ajouter plus de logique à $_POST prétraitement (unescape lorsque magic quotes sont activés est un commun) sans pourchasser tout le lieu s dans votre code où vous avez utilisé des données POST, et vous évite d'énormes maux de tête lorsque vous réalisez qu'il existe quelques champs POST dans lesquels vous avez besoin de balises HTML. Généralement, c'est une très mauvaise idée de changer directement l'un des superglobals.

De même, il est préférable d'assainir les données en sortie, pas en entrée. Différentes utilisations nécessiteront des méthodes différentes, par exemple, si vous utilisez

<div class="user_photo"> 
    <img src="<?php echo photo_path($user_id) ?>" alt="<?php echo $user_name ?>" /> 
</div> 

alors $user_name est un vecteur d'attaque XSS et strip_tags ne vous aide pas contre du tout; vous auriez besoin de htmlspecialchars. Si les données utilisateur sont utilisées comme URL, vous aurez besoin d'une autre méthode pour vous défendre contre les URL javascript: et ainsi de suite.