23 Mar 2022

Security Provider SecurityScorecard’s New WordPress Plugin Contains Security Vulnerability

One of the indications that something is very wrong with the security industry is how insecure the software and hardware of companies in it is. The latest example of that we ran across involves a company named SecurityScorecard, which we had not heard of before.

Yesterday they introduced a WordPress plugin SecurityScorecard Seal of Trust Badge, which appeared on our radar due to monitoring we do to keep track of security issues in WordPress plugins. That plugin is described as:

Quickly and easily add the SecurityScorecard badge of trust anywhere on your website. Simply add the shortcode in your content or use the installable widget to add it to your theme.

The page for the plugin describeds the company this way:

SecurityScorecard, the leader in cybersecurity ratings, continuously monitors and scores over 12 million organizations using a familiar A-F grade scale that correlates with breach risk. Their platform uses proprietary techniques to identify the external digital assets that belong to an organization, and assess them for security issues.

Looking over their website, they look like most security companies, one that should probably be avoided. In the datasheet that is supposed to explain their scoring system, not only are they rather vague on how that is computed, but they do rather inexplicably claim the US Chamber of Commerce is a “security rating expert”:

In conjunction with the US Chamber of Commerce and other security ratings experts, SecurityScorecard helped shape and then adopted these guidelines for fair and accurate security ratings.

If SecurityScorecard’s new WordPress plugin is any indication, they don’t seem to be great at security.

The plugin contains less than 200 lines of code, but managed to include a fairly easy to spot vulnerability. That is vulnerability that both involves a failure to do basic security, but also one that should have been caught a security review. It certainly would have been caught with the type of security review we do of plugins.

As mentioned in the description of the plugin, one of the ways it can be accessed is through a shortcode. A common security issue with shortcodes is that user input passed in to them is output without first being sanitized, validated, and or escaped. More broadly, many security issues involve improper trust of user input. That is the case here.

The shortcode is registered to be accessed using “ssc-badge” and that causes the function sscbadge_ssc_badge_shortcode_function() to run:

183
add_shortcode('ssc-badge', 'sscbadge_ssc_badge_shortcode_function');

The function is as follows:

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
function sscbadge_ssc_badge_shortcode_function($atts)
{
    $atts = shortcode_atts(array(
        'domain' => '',
        'hide_attribution' => '0',
    ), $atts, 'ssc-badge');
 
	$hideAttribution = $atts['hide_attribution'];
 
    $urlparts = parse_url(home_url());
    $domain = ($atts['domain'] !== '') ? $atts['domain'] : str_replace('www.','',$urlparts['host']);
    $badgeTitle = esc_attr(get_bloginfo('name')) . ' Security Rating';
 
    $html = sscbadge_print_bagde_frontend_html($domain, $hideAttribution);
 
    return $html;
}

The first line of that function brings in user input in the form of shortcode attributes domain and hide_attribution. Both are then passed to the function sscbadge_print_bagde_frontend_html() without sanitization or validation.

In that second function, the value of domain is output without being escaped:

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
function sscbadge_print_bagde_frontend_html($domain, $hideattribution)
{
 
	$html = '';
 
	if ($domain) {
		$html .= '<iframe loading="lazy" src="https://securityscorecard.com/security-rating/badge/' . $domain . '" width="256" height="100" frameborder="0"><br />
</iframe>';
	}
 
	if ($hideattribution == '0' || $hideattribution == '') {
 
		$badgeTitle = esc_attr(get_bloginfo('name')) . ' Security Rating';
 
		$html .= sprintf('<div class="ssc-powered-by" style="width:256px; text-align:center; ">
		<a href="https://securityscorecard.com/security-rating/%1$s?utm_medium=badge&utm_source=%1$s&utm_campaign=wp-plugin" class="securityscorecard-attribution-link" target="_BLANK" title="%2$s" alt="%2$s">
		<svg viewBox="0 0 20 25" width="14" style="vertical-align:text-bottom">
		  <path d="M131.735 17.249V16.2048C131.484 16.5769 131.153 16.8815 130.767 17.0933C130.382 17.305 129.954 17.4179 129.518 17.4226C127.807 17.4226 126.599 16.0312 126.599 13.7547C126.609 11.5071 127.813 10.0709 129.518 10.0709C129.955 10.0755 130.385 10.1899 130.77 10.4044C131.156 10.6189 131.487 10.9271 131.735 11.3031V7.57736H132.753V17.249H131.735ZM131.735 15.3355V12.1738C131.52 11.8353 131.23 11.5558 130.89 11.359C130.549 11.1621 130.169 11.0537 129.78 11.0428C128.45 11.0428 127.662 12.1999 127.662 13.7547C127.662 15.3095 128.449 16.4521 129.78 16.4521C130.168 16.4439 130.548 16.3382 130.888 16.1438C131.228 15.9494 131.519 15.6721 131.735 15.3355Z" fill="white"></path>
		  <path d="M16.4242 16.1542L16.4229 21.3596L20.7506 18.7547L20.7478 13.5276L16.4242 10.9213V16.1542Z" fill="#6641f3"></path>
		  <path d="M6.05225 22.398L10.3758 25L14.6953 22.4009V17.1955L6.05225 22.398Z" fill="#6641f3"></path>
		  <path d="M20.7469 11.4435L20.7441 6.24966L16.4247 3.64624L12.1177 6.24242L20.7469 11.4435Z" fill="#6641f3"></path>
		  <path d="M6.05518 9.89587V15.1056L10.376 17.709L14.6955 15.1114V9.89587L10.376 7.29245L6.05518 9.89587Z" fill="#6641f3"></path>
		  <path d="M0.00277065 13.5406L0 18.7547L4.3236 21.3567L8.64997 18.7518L0.00277065 13.5406Z" fill="#6641f3"></path>
		  <path d="M4.32611 3.64624L0.00667689 6.2511L0.00390625 11.4579L4.32611 14.0642V3.64624Z" fill="#6641f3"></path>
		  <path d="M10.376 5.20828L14.6955 2.60486L10.376 0L6.05518 2.60486V7.81314L10.376 5.20828Z" fill="#6641f3"></path>
		</svg> %3$s
		</a>
	  </div>', $domain, $badgeTitle, 'Powered by SecurityScorecard');
	}
 
	return $html;
 
}

As the proof of concept below confirms, that permits authenticated persistent cross-site scripting (XSS) to occur for low level WordPress users.

Failed Review?

Before WordPress plugin are allowed in to WordPress’ plugin directory, they are supposed to go through a review that includes reviewing the security of the plugin. That should have caught this issue, but either the review wasn’t done or it failed. That has been a reoccurring issue and might be explained by a fabulist leading the team running that directory.

WordPress Causes Full Disclosure

As a protest of the moderators of the WordPress Support Forum’s continued inappropriate behavior we changed from reasonably disclosing to full disclosing vulnerabilities for plugins in the WordPress Plugin Directory in protest, until WordPress gets that situation cleaned up, so we are releasing this post and then leaving a message about that for the developer through the WordPress Support Forum. (For plugins that are also in the ClassicPress Plugin Directory, we will follow our reasonable disclosure policy.)

You can notify the developer of this issue on the forum as well.

Hopefully, the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that, but considering that they believe that having plugins, which have millions installs, remain in the Plugin Directory despite them knowing they are vulnerable is “appropriate action”, something is very amiss with them (which is even more reason the moderation needs to be cleaned up).

If the moderation is cleaned up, it would also allow the possibility of being able to use the forum to start discussing fixing the problems caused by the very problematic handling of security by the team running the Plugin Directory, discussions which they have for years shut down through their control of the Support Forum.

Update: To clear up the confusion where developers claim we hadn’t tried to notify them through the Support Forum (while at the same time moderators are complaining about us doing just that), here is the message we left for this vulnerability:

Is It Fixed?

If you are reading this post down the road the best way to find out if this vulnerability or other WordPress plugin vulnerabilities in plugins you use have been fixed is to sign up for our service, since what we uniquely do when it comes to that type of data is to test to see if vulnerabilities have really been fixed. Relying on the developer’s information can lead you astray, as we often find that they believe they have fixed vulnerabilities, but have failed to do that.

Proof of Concept

Creating a new post as a user with the Author role, which doesn’t have the unfiltered_html, with the following shortcode will cause an alert box with any available cookies to be shown when hovering over the plugin’s content on the resulting page.

[ssc-badge domain='" onmouseover="alert(document.cookie);']

Concerned About The Security of the Plugins You Use?

When you are a paying customer of our service, you can suggest/vote for the WordPress plugins you use to receive a security review from us. You can start using the service for free when you sign up now. We also offer security reviews of WordPress plugins as a separate service.

Leave a Reply

Your email address will not be published.