Coordinated Disclosure Timeline
- 05/12/2020: Report sent to Zepto.JS
- 03/25/2021: Disclosure deadline reached.
- 04/01/2021: Publication as per our disclosure policy.
Summary
Potential mXSS in Zepto.JS
Product
Zepto.JS
Tested Version
Latest vulnerable version: 1.2.0 (master, b5ed8d607f67724788ec9ff492be297f64d47dfc)
Details
Potential mXSS
jQuery’s htmlPrefilter
functionality is considered unsafe as of CVE-2020-11022, see additional details here: GHSA-gxr4-xjj5-5px2. The problem was that htmlPrefilter
enabled new mXSS attacks when expanding self-closing tags (<tag/>
). This function will apply a regular expression to convert <tag/>
into <tag></tag>
:
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi
...
htmlPrefilter: function( html ) {
return html.replace( rxhtmlTag, "<$1></$2>" );
return html;
}
If developers sanitize untrusted HTML (e.g.: using DOMPurify) and then pass the clean HTML into this filter (e.g.: when calling jQuery()
), the resulting HTML may mutate into dangerous HTML. For example, the following image tag with two string literal attributes:
<img alt="<x" title="/><img src=url404 onerror=alert(0)>">
will mutate into:
<img alt="<x" title="></x"><img src=url404 onerror=alert(0)>">
Additional attack vectors can be found in jQuery tests.
Note that while some of these test-strings seem suspicious, they will not actually cause code to be run unless they are transformed by the unsafe htmlPrefilter
.
Zepto contains a port of jQuery’s htmlPrefilter
functionality, and is vulnerable to some of the same attack vectors. See this example which will show an alert:
<html>
<head>
<script type="text/javascript" src="./zepto.js"></script></head>
<body>
<script type="text/javascript">
$.zepto.fragment('<noscript/><img src=url404 onerror=alert(0)>')
</script>
</body>
</html>
Impact
This issue may lead to a Cross-Site Scripting vulnerability (mXSS)
Credit
This issue was discovered by Esben Sparre Andreasen (@esbena) performing a Variant Analysis of CVE-2020-11022 which was found and reported by Masato Kinugawa (@masatokinugawa).
Contact
You can contact the GHSL team at securitylab@github.com
, please include GHSL-2020-098
in any communication regarding this issue.