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 |