24 May

Tip For Security Researchers: wp_insert_post() and wp_update_post() Sanitize the Submitted Input

From reviewing lots of vulnerability reports one of our big takeaways is that the proper testing of suspected vulnerabilities often isn’t being done by security researchers. Without doing that you miss an easy to chance to catch things happening that nullify potential vulnerabilities in part or sometimes in full.

One recent example we noticed repeating an issue from a previous false report of a vulnerability, involves a correctly identified cross-site scripting (CSRF) vulnerability in a plugin that the discoverer then extrapolated could be lead to persistent cross-site scripting (XSS) due to what the CSRF vulnerable function does:

The function is intended to create or modify a slideshow object stored in the wp_posts table. However it doesn’t check the post type so it can be maliciously used to modify anything in that table, including normal posts and pages. This way the attacker can inject arbitrary JavaScript on the site, escalating this bug to stored XSS.

Looking at the relevant code you can certainly see why they might believe this since you can see in the plugin’s code that no sanitization is done on the POST variable “content” before modifying a post:

        //edit post
        $slide_type = htmlspecialchars($_POST['slide_type']);

        $title = htmlspecialchars($_POST['title']);
        $content = $_POST['content'];

        // Create post object
        $my_post = array(
          'post_title'    => $title,
          'post_content'  => $content,

        // Insert the post into the database
        wp_update_post( $my_post );

Testing this out though would have shown that the sanitization is being done at some point and therefore the cross-site scripting can not occur.

The harder method to find this out would be to follow the path the data takes from the plugin into WordPress. If you do that you can see that the function wp_update_post() ends by calling the function wp_insert_post(), which in turns

passes data through sanitize_post(), which itself handles all necessary sanitization and validation (kses, etc.).

So that is what prevents the persistent cross-site scripting (XSS) from occurring, but with proper testing you wouldn’t need to know that to have avoid this type of mistake.

Leave a Reply

Your email address will not be published. Required fields are marked *