WordPress automatically adds slashes to all POST data
First published on November 14, 2012
Since WordPress 1.5 (released in 2005) and up to and including WordPress 3.5, WordPress has been effectively forcing the “magic_quotes_gpc” setting to be on. Such behavior is currently implemented in wp-settings.php by calling the function wp_magic_quotes(), which does the following:
function wp_magic_quotes() { // If already slashed, strip. if ( get_magic_quotes_gpc() ) { $_GET = stripslashes_deep( $_GET ); $_POST = stripslashes_deep( $_POST ); $_COOKIE = stripslashes_deep( $_COOKIE ); } // Escape with wpdb. $_GET = add_magic_quotes( $_GET ); $_POST = add_magic_quotes( $_POST ); $_COOKIE = add_magic_quotes( $_COOKIE ); $_SERVER = add_magic_quotes( $_SERVER ); // Force REQUEST to be GET + POST. $_REQUEST = array_merge( $_GET, $_POST ); }
You might discover this if you’re dealing with POST data, have long vowed to never turn on the “magic_quotes_gpc” setting (which is deprecated in PHP 5.3 and removed in PHP 5.4) and are manually escaping data with specific-use functions such as mysqli_real_escape_string(), only to discover that items are being double-encoded and/or you are being forced to use stripslashes (or the WordPress-specific stripslashes_deep).
Despite the resulting frustration and surprise to many developers, WordPress has reasons for keeping this seemingly odd behavior, and you can read about this here and here. In short, WordPress is trying to protect its millions of users from the onslaught of basic vulnerabilities that removing this behavior would cause. These vulnerabilities would be exposed in its huge database of publicly contributed plugins of varying qualities; some plugins don’t properly escape outside data.
At some point, this will need to be resolved, but if you’ve run into this problem when developing something in WordPress, now you know the 7+ years of history behind it!