web-dev-qa-db-fra.com

Pourquoi les variables $ _POST s'échappent-elles en PHP?

Lorsque mon script PHP reçoit des données d'une AJAX POST, le $_POST les variables sont échappées. La chose vraiment étrange est que cela ne se produit que sur mon serveur de production (exécutant PHP 5.2.12 sous Linux) et non sur mon serveur local (exécutant PHP 5.3 .1 sous Windows).

Voici le code AJAX:

var pageRequest = false;
if(window.XMLHttpRequest)     pageRequest = new XMLHttpRequest();
else if(window.ActiveXObject) pageRequest = new ActiveXObject("Microsoft.XMLHTTP");

pageRequest.onreadystatechange = function() { }

var q_str = 'data=' + " ' ";

pageRequest.open('POST','unnamed_page.php',true);

pageRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
pageRequest.setRequestHeader("Content-length", q_str.length);
pageRequest.setRequestHeader("Connection", "close");

pageRequest.send(q_str);

Y a-t-il une raison à cela? Et comment dois-je résoudre ce problème afin qu'il fonctionne sur les deux serveurs?

Edit: J'ai les paramètres suivants pour magic_quotes:

                     Local   Master

magic_quotes_gpc     On      On
magic_quotes_runtime Off     Off
magic_quotes_sybase  Off     Off
39
Nathan Osman

Vous avez probablement des guillemets magiques activés sur le serveur Linux: magic_quotes

Lorsque magic_quotes est activé, tous les '(guillemet simple), "(guillemet double),\(barre oblique inverse) et NUL sont automatiquement échappés avec une barre oblique inverse.

Ils sont une bonne chose à désactiver, car ils vont être supprimés de PHP 6 à partir de toute façon. Vous devriez également pouvoir les désactiver dans votre script: set-magic-quotes-runtime Vous ne pouvez pas désactiver la partie de magic_quotes responsable de l'échappement des données POST pendant l'exécution. Si vous le pouvez, désactivez-les dans php.ini. Si vous ne pouvez pas le faire, vérifiez si le magic_quotes sont activés et font un striplashes () sur tout contenu que vous récupérez de POST:

if (get_magic_quotes_gpc())  
 $my_post_var = stripslashes($_POST["my_post_var"]);
68
Pekka

Je ne pense pas que cela s'applique dans votre cas, mais j'avais juste un problème similaire. Je chargeais une installation WordPress avec un site, donc je pouvais afficher les publications récentes sur toutes les pages. Il s'avère WordPress échappe à toutes les vars $ _POST, non quelle que soit la valeur de magic_quotes.

Je le mentionne parce que c'était frustrant de comprendre, et googler pour une réponse m'a amené ici.

Voici comment je l'ai corrigé dans mon cas:

$temp_POST = $_POST;
require '../www/wp_dir/wp-load.php'; // Loading WordPress
$_POST = $temp_POST;
28
Syntax Error

Il s'agit d'une PHP "fonctionnalité" connue sous le nom de Magic Quotes , qui est maintenant déconseillée dans PHP 5.3 et supprimée dans PHP 5.4 .

Il est facile de désactiver la nuisance idiote dans php.ini.

9
Matchu

Vous avez probablement des citations magiques activées dans votre environnement de production. Inspectez la sortie phpinfo().

Vous pouvez exécuter toutes vos entrées via quelque chose comme ceci pour supprimer les guillemets:

        /* strip slashes from the string if magic quotes are on */
    static function strip_magic_slashes($str)
    {
            return get_magic_quotes_gpc() ? stripslashes($str) : $str;
    }
4
BojanG

J'ai donc parlé à un WordPress (# 40476. $ _POST values ​​'et\sont sûrs de s'échapper avec une barre oblique = ) et il a dit:

À l'époque, il y a de nombreuses lunes, WordPress a suivi aveuglément PHP en acceptant que toutes les valeurs superglobales soient réduites. PHP plus tard, a renversé l'idée en quelque chose de plus sain d'esprit que vous voyez aujourd'hui, mais le mal a été fait.

WordPress en tant qu'application existait depuis assez longtemps, et il y avait suffisamment de plugins et de thèmes existants reposant sur WordPress créant un environnement sain et sain qui WordPress changerait également causerait des dommages irréparables à ces sites - introduisez des failles de sécurité, modifiez le contenu et bien d'autres choses amusantes.

https://core.trac.wordpress.org/ticket/18322 est notre ticket pour suivre cela et arriver à quelque chose de plus sain d'esprit - à court terme (et à plus long terme), nous vous demanderions si vous 'accédez aux variables $ _POST vous le faites comme tel: $ myvar = wp_unslash ($ _POST [' variable ']); pour qu'un jour, nous puissions avoir $ _POST comme tableau non barré.

Concernant la réponse donnée ici:

$temp_POST = $_POST;
require '../www/wp_dir/wp-load.php';
$_POST = $temp_POST;

Veuillez ne pas faire ça. Vous vous ouvrez simplement à des problèmes de sécurité et à des choses inattendues qui se produisent dans votre contenu où WordPress s'attend à ce que les valeurs soient réduites. À la place, utilisez simplement wp_unslash(), et si vous avez vraiment besoin d'une copie de $ _POST pour fonctionner sur vous-même, faites-le comme tel: $my_POST = wp_unslash( $_POST );.

Je devrais également ajouter - je suppose que vous faites cela parce que vous essayez d'utiliser un point de terminaison API pour quelque chose, je vous suggère fortement de passer à l'utilisation de l'API REST introduite avec WordPress 4.7 à la place, car il nous permet d'offrir une expérience beaucoup plus cohérente aux développeurs.

3
Toskan

Peut-être que le php.ini de votre serveur Linux a activé les guillemets magiques.

http://php.net/manual/en/security.magicquotes.php

C'est mauvais, bien sûr, car la fonctionnalité est obsolète et sera supprimée dans le prochain PHP 6.

Vous pouvez le désactiver dans php.ini comme ça

magic_quotes_gpc = Off

Vous pouvez le tester et le désactiver lors de l'exécution si vous ne pouvez pas accéder à votre php.ini

<?php
if (get_magic_quotes_gpc()) {
    $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
    while (list($key, $val) = each($process)) {
        foreach ($val as $k => $v) {
            unset($process[$key][$k]);
            if (is_array($v)) {
                $process[$key][stripslashes($k)] = $v;
                $process[] = &$process[$key][stripslashes($k)];
            } else {
                $process[$key][stripslashes($k)] = stripslashes($v);
            }
        }
    }
    unset($process);
}
?>

Depuis le PHP Manual

2
alex

Solution élégante, basée sur toutes les réponses

if ( get_magic_quotes_gpc() ) {
    array_walk_recursive( $_POST, function ( &$element ) {
        $element = stripslashes( $element );
    } );
}
0
Andrii