WordPress Search filter to remove possible script injections

I am trying to write a short plugin that will filter html characters from the search form. In the event someone enters in <script>alert('some infectious js!');</script> into the search form i want to remove the possibility of this command to be entered into the search form.

I tried this:

Read More
function SearchFilter( $query ) {
     if ( is_search() ) {
          $query = strip_tags($query);
          return;
     }
 }
 add_action ('pre_get_posts', 'SearchFilter');

When I go to test it, i enter <script>alert('some infectious js!');</script> above into the search field and all I get is a blank white page in wordpress. The search still works but anytime i type in script it breaks the box. This seems odd that wordpress doesn’t handle this by default OR am i totally wrong on this?

Thanks in advance.

Related posts

Leave a Reply

1 comment

  1. WP does handle that case already, the script will never be executed, because the function the_search_query() will return its output escaped.

    Escaping this prior to the actual search would break searching in code. If you blog about script injections your visitors should be able to search for that.

    Update

    Here is one of my older plugins. It enables searching in escaped code and breaks the search for unescaped <, & or >. Unfortunately, it has some side effects when it is used together with search plugins like Relevanssi or Search Unleashed.

    <?php # -*- coding: utf-8 -*-
    /**
     * Plugin Name: T5 Search escaped characters
     * Description: Enable to search for escaped &lt;, &gt; and &amp;.
     * Plugin URI:
     * Version:     2012.08.25
     * Author:      Thomas Scholz
     * Author URI:  http://toscho.de
     * License:     MIT
     * License URI: http://www.opensource.org/licenses/mit-license.php
     */
    
    add_filter( 'posts_search', 't5_search_escaped_characters', 10, 2 );
    
    function t5_search_escaped_characters( $search, $obj = NULL )
    {
        if ( $obj->is_search and empty ( $search ) and is_main_query() )
        {
            remove_filter( current_filter(), __FUNCTION__ );
            return ' AND 1 = 2 ';
        }
        $s   = $obj->query_vars['s'];
        // Double-encoding FALSE in case another plugin did that already.
        $esc = htmlspecialchars( $s, ENT_NOQUOTES, 'utf-8', FALSE );
        return str_replace( "%$s%", "%$esc%", $search ) . ' ';
    }
    

    Might be a start if you want to touch the search string early enough.