WordPress Plugin TranslatePress < 2.0.9 - Authenticated Stored Cross-Site Scripting

We discovered a Stored Cross-site Scripting (XSS) vulnerability on the WordPress Plugin, TranslatePress, on 06 August 2021. This WordPress translation plugin assists with the translation of website content from and to various languages, and has accumulated more than 100,000 active installations. This security issue was promptly highlighted to the respective vendor who has followed up with reporting and patching this vulnerability.

Vulnerability Overview

DescriptionAuthenticated Stored Cross-Site Scripting
Affected PluginTranslatePress (https://wordpress.org/plugins/translatepress-multilingual/)
Affected Versions< 2.0.9
Active installations100,000+
Fully Patched Version2.0.9
CVE IDCVE-2021-24610
CVSS Score4.8 (Medium)
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N
Discovered byNosa Shandy – Security Researcher & Consultant at PT. softScheck Siber Securindo

Vulnerability Details

The TranslatePress plugin does not implement a proper input filter on the ‘translated’ parameter for when user input is submitted into the database. The ‘trp_sanitize_string’ filter function only checks for the existence of ““, which is removed to prevent JavaScript injection. Although the script tags are mostly used for XSS, this is not a necessary requirement for causing an XSS vulnerability. There are other malicious characters which may also be used to trigger the XSS vulnerability. Hence, we recommend the proper implementation of a strong input filter.

Vulnerable Code:

  • File: includes/functions.php
  • Line: 151-170

function trp_sanitize_string( $filtered ){
$filtered = preg_replace( ‘/<script\b[^>]*>(.*?)<\/script>/is’, ”, $filtered );

// don’t remove \r \n \t. They are part of the translation, they give structure and context to the text.
//$filtered = preg_replace( ‘/[\r\n\t ]+/’, ‘ ‘, $filtered );
$filtered = trim( $filtered );

$found = false;
while ( preg_match(‘/%[a-f0-9]{2}/i’, $filtered, $match) ) {
$filtered = str_replace($match[0], ”, $filtered);
$found = true;
}

if ( $found ) {
// Strip out the whitespace that may now exist after removing the octets.
$filtered = trim( preg_replace(‘/ +/’, ‘ ‘, $filtered) );
}

return $filtered;
}

Proof of Concept

The following steps may be performed to replicate this vulnerability:

  1. Login as admin and go to the Translate front-end page (/?trp-edit-translation=true)
  2. Select the ‘Search’ string to be translated, and input the following payload as the Translated Text:
img-wp-translate-2
  1. Access the front-end as any user to trigger the XSS
img-wp-translate-1

Disclosure Timeline
The timeline for the disclosure of this vulnerability is as follows:

06 August 2021Initial Discovery and Report made through WPScan
06 August 2021WPScan verified the issue and reserved CVE-2021-24610 for it
06 August 2021Vendor was contacted by WPScan
09 August 2021Wait for the patch
24 August 2021Fixed & Scheduled disclosure of the vulnerability
30 August 2021Approval and addition of CVE-2021-24610 to the WPScan database
06 August 2021Initial Discovery and Report made through WPScan
06 August 2021WPScan verified the issue and reserved CVE-2021-24610 for it

Solution
This security issue can be remediated through an update of the plugin to version 2.0.9 and above.

Conclusion
The TranslatePress plugin only performs input filtering for the script tags and removes it using the preg_replace function. This type of input filter is deemed to be insufficient as there are other malicious characters that can similarly be abused to inject JavaScript. It is recommended to implement a strong input filter using the whitelist approach and perform encoding before any usage of user input data.

Instagram

Instagram has returned invalid data.