2

I'm using the WordPress 'posts_where' filter (https://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where) to alter my queries as below:

        function filter_my_search($where=''){
            global $wpdb;

        if(isset($_GET['q'])) {

            $where .= 'AND (((' . $wpdb->posts . '.post_title LIKE "%'.$_GET["q"].'%") OR (' . $wpdb->posts . '.post_content LIKE "%'.$_GET["q"].'%")))';
        }
        return $where;
    }
add_filter('posts_where', 'filter_my_search');

So a query is being run, and I'm intercepting the where clause, and adding an extra condition. Would that code be susceptible to SQL injection?

1 Answer 1

4

No! WordPress will not protect against SQL injection in this case. You need to do so yourself, using $wpdb->esc_like and $wpdb->prepare:

if ( isset( $_GET['q'] ) ) {    
    // WordPress forces magic quotes (god knows why), unslash it
    $value = wp_unslash( ( string ) $_GET['q'] );

    // Escape like wildcards so that MySQL interprets them as literals
    $value = $wpdb->esc_like( $value );

    // Create our "true" like query
    $value = "%$value%";

    // Now inject it safely
    $where .= $wpdb->prepare(
        " AND ( ( $wpdb->posts.post_title LIKE %s ) OR ( $wpdb->posts.post_content LIKE %s ) )",
        $value,
        $value
    );
}
2
  • I see, would you have to do anything similar for functions such as update_post_meta, or was the above necessary because I was specifically writing MySQL clauses?
    – gray
    Commented Apr 22, 2015 at 13:03
  • 1
    No, yep :) Always escape when writing SQL, whereas any core WordPress function that writes to the db will escape the arguments for you. Commented Apr 22, 2015 at 14:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.