{"id":"GHSA-5cp4-xmrw-59wf","summary":"XSS via JQLite DOM manipulation functions in AngularJS","details":"### Summary\nXSS may be triggered in AngularJS applications that sanitize user-controlled HTML snippets before passing them to `JQLite` methods like `JQLite.prepend`, `JQLite.after`, `JQLite.append`, `JQLite.replaceWith`, `JQLite.append`, `new JQLite` and `angular.element`.\n\n### Description\n\nJQLite (DOM manipulation library that's part of AngularJS) manipulates input HTML before inserting it to the DOM in `jqLiteBuildFragment`.\n\nOne of the modifications performed [expands an XHTML self-closing tag](https://github.com/angular/angular.js/blob/418355f1cf9a9a9827ae81d257966e6acfb5623a/src/jqLite.js#L218).\n\nIf `jqLiteBuildFragment` is called (e.g. via `new JQLite(aString)`) with user-controlled HTML string that was sanitized (e.g. with [DOMPurify](https://github.com/cure53/DOMPurify)), the transformation done by JQLite may modify some forms of an inert, sanitized payload into a payload containing JavaScript - and trigger an XSS when the payload is inserted into DOM.\n\nThis is similar to a bug in jQuery `htmlPrefilter` function that was [fixed in 3.5.0](https://blog.jquery.com/2020/04/10/jquery-3-5-0-released/).\n\n### Proof of concept\n\n```javascript\nconst inertPayload = `\u003cdiv\u003e\u003cstyle\u003e\u003cstyle/\u003e\u003cimg src=x onerror=\"alert(1337)\"/\u003e` \n```\nNote that the style element is not closed and `\u003cimg` would be a text node inside the style if inserted into the DOM as-is.\nAs such, some HTML sanitizers would leave the `\u003cimg` as is without processing it and stripping the `onerror` attribute.\n\n```javascript\nangular.element(document).append(inertPayload);\n```\nThis will alert, as `\u003cstyle/\u003e` will be replaced with `\u003cstyle\u003e\u003c/style\u003e` before adding it to the DOM, closing the style element early and reactivating `img`.\n\n### Patches\nThe issue is patched in `JQLite` bundled with angular 1.8.0. AngularJS users using JQuery should upgrade JQuery to 3.5.0, as a similar vulnerability [affects jQuery \u003c3.5.0](https://github.com/jquery/jquery/security/advisories/GHSA-gxr4-xjj5-5px2).\n\n### Workarounds\nChanging sanitizer configuration not to allow certain tag grouping (e.g. `\u003coption\u003e\u003cstyle\u003e\u003c/option\u003e`) or inline style elements may stop certain exploitation vectors, but it's uncertain if all possible exploitation vectors would be covered. Upgrade of AngularJS to 1.8.0 is recommended.\n\n### References\nhttps://github.com/advisories/GHSA-mhp6-pxh8-r675\nhttps://github.com/jquery/jquery/security/advisories/GHSA-gxr4-xjj5-5px2\nhttps://github.com/jquery/jquery/security/advisories/GHSA-jpcq-cgw6-v4j6\nhttps://blog.jquery.com/2020/04/10/jquery-3-5-0-released/\nhttps://snyk.io/vuln/SNYK-JS-ANGULAR-570058","modified":"2021-10-08T21:25:58Z","published":"2020-08-05T21:47:02Z","database_specific":{"severity":"MODERATE","github_reviewed":true,"github_reviewed_at":"2020-08-05T21:46:46Z","nvd_published_at":null,"cwe_ids":["CWE-79"]},"references":[{"type":"WEB","url":"https://github.com/google/security-research/security/advisories/GHSA-5cp4-xmrw-59wf"},{"type":"WEB","url":"https://github.com/jquery/jquery/security/advisories/GHSA-gxr4-xjj5-5px2"},{"type":"WEB","url":"https://github.com/jquery/jquery/security/advisories/GHSA-jpcq-cgw6-v4j6"},{"type":"WEB","url":"https://blog.jquery.com/2020/04/10/jquery-3-5-0-released"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-mhp6-pxh8-r675"},{"type":"PACKAGE","url":"https://github.com/angular/angular.js"},{"type":"WEB","url":"https://snyk.io/vuln/SNYK-JS-ANGULAR-570058"}],"affected":[{"package":{"name":"angular","ecosystem":"npm","purl":"pkg:npm/angular"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"1.8.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2020/08/GHSA-5cp4-xmrw-59wf/GHSA-5cp4-xmrw-59wf.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L"}]}