Shariff Wrapper <= 4.6.20 - Authenticated (Contributor+) Cross-Site Scripting
Description
The Shariff Wrapper plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'headline' parameter in the [shariff] shortcode in all versions up to, and including, 4.6.20 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. The vulnerability occurs because the plugin uses a custom wp_kses implementation with permissive allowed HTML tags, and then performs a str_replace operation that injects HTML after sanitization, allowing event handlers to be introduced through the %total placeholder in the style attribute.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v4.6.21
Source Code
WordPress.org SVNI want a horizontal line above my Shariff buttons! ... For example, enter the following code to create a horizontal line and a headline: `<hr style='margin:20px 0'><p>Please share this post:</p>`" * This is provided as an example for the *design tab* (admin setting), but the FAQ also says "Use…
Show full research plan
I want a horizontal line above my Shariff buttons! ... For example, enter the following code to create a horizontal line and a headline: <hr style='margin:20px 0'><p>Please share this post:</p>"
* This is provided as an example for the design tab (admin setting), but the FAQ also says "Use the headline attribute to add or remove [the headline]...".
* So the headline attribute in the shortcode is expected to contain HTML.
* **User Role:** Contributor.
* **Action:** Create a post.
* **Shortcode:** `[shariff headline="<span style='font-family:%total'></span>" total='";breakout_here...']`
* Wait, does the shortcode support `total`?
* If not `total`, what is `%total` replaced with?
* Could it be the `total` from the *options*? No, PR:L.
* What if `%total` is replaced by the *content* of the shortcode?
* `[shariff headline="...%total..."]My Payload[/shariff]`
* No, `[shariff]` is usually self-closing.
* What about the `totalnumber` service?
* If `services="totalnumber"`, does the plugin use a value from somewhere?
* Let's look at the `final
Summary
The Shariff Wrapper plugin is vulnerable to Stored Cross-Site Scripting via the 'headline' and 'headline_zero' attributes in the [shariff] shortcode. This is caused by the plugin replacing a %total placeholder with a HTML span tag without re-sanitizing the resulting string, allowing authenticated attackers with contributor-level permissions to inject arbitrary web scripts.
Vulnerable Code
// shariff.php lines 1222-1230 in v4.6.20 if ( 0 === $share_counts['total'] && array_key_exists( 'headline_zero', $atts ) && ! empty( $atts['headline_zero'] ) ) { $atts['headline_zero'] = str_replace( '%total', '<span class="shariff-total">' . absint( $share_counts['total'] ) . '</span>', $atts['headline_zero'] ); $output .= '<div class="ShariffHeadline">' . $atts['headline_zero'] . '</div>'; } else { $atts['headline'] = str_replace( '%total', '<span class="shariff-total">' . absint( $share_counts['total'] ) . '</span>', $atts['headline'] ); $output .= '<div class="ShariffHeadline">' . $atts['headline'] . '</div>'; } --- // shariff.php lines 1345-1349 in v4.6.20 (CSS injection snippet) if ( array_key_exists( 'borderradius', $atts ) && array_key_exists( 'theme', $atts ) && 'round' === $atts['theme'] ) { $output .= ' shariff-borderradius'; $css = '.shariff .shariff-buttons.theme-round .shariff-borderradius{border-radius:' . $atts['borderradius'] . '%}'; if ( false === strpos( $dynamic_css, $css ) ) { $dynamic_css .= $css;
Security Fix
@@ -1222,10 +1238,10 @@ $share_counts['total'] = 0; } if ( 0 === $share_counts['total'] && array_key_exists( 'headline_zero', $atts ) && ! empty( $atts['headline_zero'] ) ) { - $atts['headline_zero'] = str_replace( '%total', '<span class="shariff-total">' . absint( $share_counts['total'] ) . '</span>', $atts['headline_zero'] ); + $atts['headline_zero'] = wp_kses( str_replace( '%total', '<span class="shariff-total">' . absint( $share_counts['total'] ) . '</span>', $atts['headline_zero'] ), $GLOBALS['allowed_tags'] ); $output .= '<div class="ShariffHeadline">' . $atts['headline_zero'] . '</div>'; } else { - $atts['headline'] = str_replace( '%total', '<span class="shariff-total">' . absint( $share_counts['total'] ) . '</span>', $atts['headline'] ); + $atts['headline'] = wp_kses( str_replace( '%total', '<span class="shariff-total">' . absint( $share_counts['total'] ) . '</span>', $atts['headline'] ), $GLOBALS['allowed_tags'] ); $output .= '<div class="ShariffHeadline">' . $atts['headline'] . '</div>'; } } @@ -1343,9 +1359,9 @@ $dynamic_css .= $css; } // Border radius? - if ( array_key_exists( 'borderradius', $atts ) && array_key_exists( 'theme', $atts ) && 'round' === $atts['theme'] ) { + if ( array_key_exists( 'borderradius', $atts ) && array_key_exists( 'theme', $atts ) && 'round' === $atts['theme'] && is_numeric( $atts['borderradius'] ) ) { $output .= ' shariff-borderradius'; - $css = '.shariff .shariff-buttons.theme-round .shariff-borderradius{border-radius:' . $atts['borderradius'] . '%}'; + $css = '.shariff .shariff-buttons.theme-round .shariff-borderradius{border-radius:' . absint( $atts['borderradius'] ) . '%}'; if ( false === strpos( $dynamic_css, $css ) ) { $dynamic_css .= $css; }
Exploit Outline
To exploit this vulnerability, an attacker with Contributor-level access or higher can create a new post or edit an existing one. They insert the [shariff] shortcode and set the 'headline' attribute to a payload that includes a legitimate HTML tag (permitted by the plugin's internal $allowed_tags list, such as <span> or <div>) coupled with a malicious event handler or an attribute-breakout sequence using the %total placeholder. For example, using [shariff headline='<span style="font-family:%total" onmouseover="alert(1)">Share this!</span>'] allows the attacker to bypass the plugin's initial sanitization logic because the malicious event handler is either not processed correctly at save-time or the %total substitution at render-time creates a context where the event handler is executed in the user's browser. Additionally, the 'borderradius' attribute can be used for CSS injection by providing non-numeric values.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.