开发者

Why are $_POST variables getting escaped in PHP?

When my PHP script receives data from an AJAX POST request, the $_POST variables are escaped. The really strange thing is that this only happens on my production server (running PHP 5.2.12 on Linux) and not on my local server (running PHP 5.3.1 on Windows).

Here is the AJAX code:

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开发者_C百科.setRequestHeader("Connection", "close");

pageRequest.send(q_str);

Is there any reason this is happening? And how should I fix this so that it works on both servers?

Edit: I have the following settings for magic_quotes:

                     Local   Master

magic_quotes_gpc     On      On
magic_quotes_runtime Off     Off
magic_quotes_sybase  Off     Off


You probably have magic quotes enabled on the Linux server: magic_quotes

When magic_quotes are on, all ' (single-quote), " (double quote), \ (backslash) and NUL's are escaped with a backslash automatically.

They're a good thing to disable, as they are going to be removed from PHP 6 onwards anyway. You should also be able to disable them inside your script: set-magic-quotes-runtime You can't deactivate the part of magic_quotes responsible for escaping POST data during runtime. If you can, disable it in php.ini. If you can't do that, do a check whether the magic_quotes are enabled, and do a stripslashes() on any content you fetch from POST:

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


I don't think this applies in your case, but I was just having a similar problem. I was loading a WordPress install along with a site, so I could show recent posts on all pages. It turns out WordPress escapes all $_POST vars, no matter what magic_quotes are set to.

I mention it because it was frustrating to figure out, and googling for an answer brought me here.

Here's how I fixed it in my case:

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


This is a PHP "feature" known as Magic Quotes, which has now been deprecated in PHP 5.3 and removed in PHP 5.4.

It is easy to disable the silly nuisance in php.ini.


You likely have magic quotes turned on in your production environment. Inspect phpinfo() output.

You can run all of your inputs through something like this to strip the quotes:

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


So I did talk to a WordPress developer (#40476. $_POST values ' and \ for sure are getting escaped with a slash) and he said:

Back in the day, many many moons ago, WordPress blindly followed PHP in accepting that all of the superglobal values should be slashed. PHP later did a reversal on the idea to something more sane which you see today, but the damage was done.

WordPress as an application had existed for long enough, and there were enough existing plugins and themes relying upon WordPress creating a sane single environment that WordPress also changing would cause irreparable damage to those sites - introduce security vulnerabilities, mangle content, and a bunch of other fun things.

https://core.trac.wordpress.org/ticket/18322 is our ticket for tracking this and getting to something more sane - in the shortterm (and longer term) we'd request that if you're accessing $_POST variables you do it as such: $myvar = wp_unslash( $_POST['variable'] ); so that one day, we'll be able to have $_POST as an unslashed array.

Concerning the answer given here:

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

Please don't do that. You're just opening yourself to security issues, and unexpected things happening to your content where WordPress does expect the values to be slashed. Instead, simply use wp_unslash(), and if you really need a copy of $_POST to operate on yourself, do it as such: $my_POST = wp_unslash( $_POST );.

I should also add - I expect you're doing this because you're trying to use an API endpoint for something, I'd highly suggest switching to using the REST API introduced with WordPress 4.7 instead, as it allows us to offer much more consistent experience to developers.


Maybe your Linux server's php.ini has magic quotes enabled.

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

This is bad of course, as the functionality is deprecated and will be removed in the forthcoming PHP 6.

You can disable it in php.ini like so

magic_quotes_gpc = Off

You can test and disable it at runtime if you can not access your 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);
}
?>

From the PHP Manual

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜