32

This question has been posed a few times in various places, but I haven't found a definative and clear answer. Most solutions involve people saying to disable Magic Quotes on the php.ini file (which I did) or modifying core WP files.

Anyways, the question is this: why is it everytime I use $wpdb->insert or $wpdb->update a slash gets added before any single quote. So for instance:

I've eaten strawberries becomes I\'ve eaten strawberries

Here's a sample code I used:

$id = $_POST['id'];
$title = $_POST['title'];
$message = $_POST['message'];

$wpdb->update('table_name', array('id'=>$id, 'title'=>$title, 'message'=>$message), array('id'=>$id))

The same problem was here: Wordpress Database Output - Remove SQL Injection Escapes but it was never solved aside from "disable magic quotes"

Community
  • 1
  • 1
J Lee
  • 1,533
  • 1
  • 14
  • 20
  • Are you sure you have magic quotes disabled? Have you checked it in `phpinfo()` – zerkms Sep 08 '11 at 00:43
  • Yea, here's the excerpt from phpinfo --> magic_quotes_gpc Off Off magic_quotes_runtime Off Off magic_quotes_sybase Off Off – J Lee Sep 08 '11 at 00:47
  • Are those extra / missing quotes in the `update()` call typos or actually in your code? – Phil Sep 08 '11 at 01:06
  • @phil the extra quotes are being added, no typos here. Take a look at the strawberry example to see what it does. It's something to do with the wpdb->insert and wpdb->update actually putting a slash in front, but I have no clue how to disable it doing that – J Lee Sep 08 '11 at 01:11
  • @fewpeople Perhaps you misunderstood. The last line of code in your question is a mess of misplaced single-quotes. Is that what it actually looks like? Also, where are you seeing the added slashes (ie, in echo'd markup, phpMyAdmin, MySQL console, etc)? – Phil Sep 08 '11 at 01:12
  • @phil the code in the explaination was wrong, see revised edit. I'm seeing the added slashes in phpMyadmin...so it's storing the data with slashes in the dB – J Lee Sep 08 '11 at 01:23

3 Answers3

70

After spending the day on this, the answer is as follows:

Wordpress escapes at the $_POST declaration, not at the actual insert, which is bizarre.

$id = stripslashes_deep($_POST['id']); //added stripslashes_deep which removes WP escaping.
$title = stripslashes_deep($_POST['title']);
$message = stripslashes_deep($_POST['message']);

$wpdb->update('table_name', array('id'=>$id, 'title'=>$title, 'message'=>$message), array('id'=>$id));

Doing this will mean that WP will not add slashes before any quotes.

J Lee
  • 1,533
  • 1
  • 14
  • 20
7

a little more info--WordPress decided to make people think they were going crazy by adding 'magic quotes' even if you've got it turned off starting in version 3.0. Any access to $_REQUEST, $_GET, $_POST, $_COOKIE, or $_SERVER will be affected. See wp-includes/load.php.

 /* Add magic quotes to $_GET, $_POST, $_COOKIE, and $_SERVER.
 * @since 3.0.0
 */
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 );
}
Ryan Horrisberger
  • 955
  • 11
  • 16
3

WordPress ignores the built in php magic quotes setting and the value of get_magic_quotes_gpc() and will always add magic quotes (even after the feature is removed from PHP in 5.4).

you can use this instead

//replace $_POST with $POST
$POST      = array_map( 'stripslashes_deep', $_POST);
$wpdb->insert( 
        'wp_mytable', 
        array( 
            'field_name'        => $POST['field_name'], 
            'type'              => $POST['type'],
            'values'            => serialize($POST['values']),
            'unanswered_link'   => $POST['unanswered_link'], 
        ), 
        array( 
            '%s','%s','%s','%s'
        ) 
    );

WordPress does this because too much core and plugin code has come to rely on the quotes being there, so disabling quotes on the super globals (as is done in both the "Basic Example" and "Good Coding Practice" examples above) is likely to cause security holes.

http://codex.wordpress.org/Function_Reference/stripslashes_deep

keithics
  • 8,576
  • 2
  • 48
  • 35
  • Interestingly enough, you can also replace the entire $_POST variable itself (instead of creating a new variable without the underscore). Not sure how advisable that is... – anon Jun 07 '18 at 16:40