Modern web applications (including mobile apps) may not be able to rely on server-side Cross-Site Scripting (XSS) filtering. This also holds for applications that work offline (e.g. use appcache and offline functionality), applications for which a server only sees encrypted data (e.g. using Web Crypto API or OpenPGP.js), websites that make use of JavaScript templating and MVC, or applications that communicate on a peer-to-peer basis and thus don’t even involve central servers. Existing browser-side XSS filters, like XSS Auditor or NoScript, fail as well, which is due to the fact that they are located outside the DOM.
To cope with this problem, XSS sanitation within the Document Object Model (DOM) is required. This poses several novel technical challenges: A DOM-based sanitizer must rely on native JavaScript functions. However, in the DOM, any function or property can be overwritten, through a class of attacks called DOM Clobbering. These attacks are known to the web security community as preparatory steps for XSS exploits. However, we give the first precise academic description of these attacks, and describe a novel application for these attack vectors, namely disabling any DOM based XSS filter.
To solve this problem, we present a two-part solution: First we show how to embed any server or client side filter securely into the DOM, by giving a methodology how to defend against DOM Clobbering attacks. Second, we give an example instantiation of an XSS filter which is highly efficient when implemented in JavaScript. Both parts are combined into a proof-of-concept implementation called DOMPurify. However, any other approach to implement XSS filters to be called from within the DOM (native browser code, browser extensions, different JavaScript libraries) also fits into our framework.