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.
Description | Authenticated Stored Cross-Site Scripting |
Affected Plugin | TranslatePress (https://wordpress.org/plugins/translatepress-multilingual/) |
Affected Versions | < 2.0.9 |
Active installations | 100,000+ |
Fully Patched Version | 2.0.9 |
CVE ID | CVE-2021-24610 |
CVSS Score | 4.8 (Medium) |
CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N |
Discovered by | Nosa 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:
- Login as admin and go to the Translate front-end page (/?trp-edit-translation=true)
- Select the ‘Search’ string to be translated, and input the following payload as the Translated Text:
- Access the front-end as any user to trigger the XSS
Disclosure Timeline
The timeline for the disclosure of this vulnerability is as follows:
06 August 2021 | Initial Discovery and Report made through WPScan |
06 August 2021 | WPScan verified the issue and reserved CVE-2021-24610 for it |
06 August 2021 | Vendor was contacted by WPScan |
09 August 2021 | Wait for the patch |
24 August 2021 | Fixed & Scheduled disclosure of the vulnerability |
30 August 2021 | Approval and addition of CVE-2021-24610 to the WPScan database |
06 August 2021 | Initial Discovery and Report made through WPScan |
06 August 2021 | WPScan 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.