Weglot WordPress - XSS

Description

This bug allows arbitrary JavaScript to be executed on a site running version 3.0 to 3.1.3 (April 2019 to December 2019) of Weglot’s WordPress plugin, Translate WP website – Weglot Translate, when specific criteria is met.

Impact

This bug only works with specific browsers out of the box. It is reproducible in Microsoft Edge as well as older browsers that lack XSS protection. However, it is exploitable in other browsers if a bypass is found in that XSS protection. Unfortunately, this happens more often than one would hope.

Is Reflective XSS relevant with modern browsers?

Most modern browsers have built-in XSS protection. Chrome has the Chrome XSS Auditor, but this was disabled on August 2019 and is being removed entirely in Chrome 78 due to a number of bypasses and security holes.1 It is being replaced by the Trusted Types API. Microsoft Edge disabled their XSS Filter in 20182. Firefox does not have an XSS auditor.

Even if most modern browsers block the attack there have been numerous bypasses in these filters over time and more are likely to be found. Because of this it is best to ensure your code is safe rather than relying on others to make it safe for your users.

Example Vulnerable URLs

  • https://example.com?s="><script>alert(1);</script>
  • https://example.com?payload="><script>alert(1);</script>

Why This Happens

Weglot creates hreflang tags to give hints to search engines about what language is used on the page.
When outputting the hreflang tags Weglot was not sanitizing the URL. This means the plugin was using the URL directly. In our exploit’s case "> would close the hreflang tag and we could add our own code such as<script>alert("xss");</script> from the url. The final output that the browser would render from our vulnerable URLs would be:

<link rel="alternate" href="https://example.com?s="><script>alert(1);</script> "hreflang="en"/>
<link rel="alternate" href="https://example.com/fr/?s="><script>alert(1);</script>" hreflang="fr"/>
 

Because we closed the link tag our <script> tag is output and able to run. This causes an alert popup to display in the user’s browser. This same bug affects the creation of the language switcher button displayed in the bottom corner of the site.

Remediation

The fix for this issue is to escape output when creating the hreflang tags and the language switcher button per the WordPress guidelines on handling user input.

This bug can be found in Custom_Url_Service_Weglot::get_link_button_with_key_code and Href_Lang_Service_Weglot::generate_href_lang_tags

The Weglot team added esc_url and esc_html before outputting their final HTML. This converts any special charcters such as < and / into their HTML counterparts. It was fixed in this commit: https://github.com/weglot/translate-wordpress/commit/5aef8ad78fffaa52b1747ed560f9ba830d11b225

Timeline

Date (YYYY-MM-DD) What
2019-11-27 Vulnerability reported to Weglot.
2019-11-28 Weglot acknowledges the report and verifies the vulnerability.
2019-12-03 Weglot states the issue was with the API not escaping the script and the issue is resolved
2019-12-03 I contact Weglot stating the vulnerability is still active.
2019-12-04 Weglot acknowledges vulnerability is still active and shared patch with me to verify.
2019-12-12 Weglot patch is available in the WordPress plugin repository

Footnotes


  1. https://groups.google.com/a/chromium.org/d/msg/blink-dev/TuYw-EZhO9g/blGViehIAwAJ ↩︎

  2. https://blogs.windows.com/windowsexperience/2018/07/25/announcing-windows-10-insider-preview-build-17723-and-build-18204/ ↩︎