Yep I fully agree that magic quotes should be disabled. I understand that wp_kses_post() and related functions have nothing to do with the database. My issue is that it seems WordPress forces magic quotes. Turning it off in php.ini will not work for WordPress because WordPress detects that it has been turned off and manually adds it back in!
See wp-includes/load.php…
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 );
}
What it’s doing is checking for magic quotes and if they are enabled it strips them. Then it manually adds magic quotes. The net result is you end up with all $_GET, $_POST, $_COOKIE and $_SERVER data with slashes added regardless of any php settings.
My question was more to do with when writing plugins do we have to then manually strip the slashes away before calling the various database functions? As you say the database functions handle escaping for us using placeholders. So in theory we should be calling stripslashes_deep on any data before passing it to these database functions.
Upon investigating the code further it appears that yes we have to manually call stripslashes_deep on any input data which could contain escaped characters before we pass it to the $wpdb methods. I can confirm that WordPress actually does this itself in core code.
In wp-includes/post.php inside wp_insert_post()
$data = stripslashes_deep( $data );
So it appears to me that as a general rule we should be calling stripslashes_deep() on any input data before calling the $wpdb methods. Also before calling wp_kses(), wp_kses_post() and wp_kses_data() we should be calling stripslashes_deep() on any data first.
Of course this isn’t ideal, no idea why WordPress would be forcing magic quotes when as you say it is being phased out of PHP. Escaping should be done to data when outputting it to an external system (such as the database) using a method specific to that external system. Forcing magic quotes on all input data is making the assumption that the data is going to one place only, the database. Escaping should be done on output not input. Validation should be done on input.