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

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:

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.