| <!doctype html> |
| <html> |
| <head> |
| <meta http-equiv="Content-Security-Policy" content="trusted-types dompurify#demo sanitize-using-dompurify my-policy"> |
| <script src="../dist/purify.js" data-tt-policy-suffix="demo"></script> |
| <style> |
| div { |
| border: 1px solid green; |
| padding: 5px; |
| margin: 5px; |
| } |
| </style> |
| </head> |
| <body> |
| <a href="https://github.com/WICG/trusted-types">Trusted Types DOMPurify demo</a> |
| <div id="sanitized-directly"></div> |
| <div id="sanitized-via-policy"></div> |
| <div id="sanitized-via-policy2"></div> |
| <div id="raw"></div> |
| <form name="loadScript"> |
| <input name="url"> |
| <button type="submit">Load script</button> |
| </form> |
| <script> |
| |
| // Specify dirty HTML |
| const dirty = '<p onclick=alert(2)>HELLO<iframe srcdoc="<script>alert(1)</scr'+'ipt>"></ifrAMe><br>goodbye</p>'; |
| |
| // Use DOMPurify directly. |
| document.getElementById('sanitized-directly').innerHTML = DOMPurify.sanitize(dirty, {RETURN_TRUSTED_TYPE: true}); |
| |
| // .. or wrap DOMPurify in TT policy itself. |
| const sanitizer = trustedTypes.createPolicy('sanitize-using-dompurify', { |
| // This code block needs security review, as it's capable of causing DOM XSS. |
| createHTML(dirty) { return DOMPurify.sanitize(dirty, {RETURN_TRUSTED_TYPE: true}) } |
| }); |
| |
| // You can use policies that don't use DOMPurify as well. |
| const myPolicy = trustedTypes.createPolicy('my-policy', { |
| // This code block needs security review, as it's capable of causing DOM XSS. |
| createHTML(dirty) { return dirty.replace(/</g, '<') }, |
| createScriptURL(dirty) { |
| const u = new URL(dirty, document.baseURI); |
| if (u.origin == window.origin) { |
| return u.href; |
| } |
| throw new Error('Only same-origin scripts, please'); |
| }, |
| }); |
| |
| |
| document.getElementById('sanitized-via-policy').innerHTML = sanitizer.createHTML(dirty); |
| |
| document.getElementById('sanitized-via-policy2').innerHTML = myPolicy.createHTML(dirty); |
| |
| // Now you know that any DOM XSS* can only be caused by flaws in configured policies. |
| // (e.g. a bug in DOMPurify.sanitize can cause XSS, but nothing more). |
| |
| // This will fail. No more DOM XSSes outside of policy definitions. |
| // Writing strings to DOM is only possible through policies. |
| try { |
| document.getElementById('raw').innerHTML = dirty; |
| } catch(e) {} |
| |
| document.forms['loadScript'].onsubmit = (e) => { |
| e.preventDefault(); |
| const url = e.target['url'].value; |
| const s = document.createElement('script'); |
| try { |
| // This will fail, you need a TrustedScriptURL. |
| s.src = url; |
| console.log('Should not happen'); |
| } catch(e) {}; |
| s.src = myPolicy.createScriptURL(url); |
| console.log('Will load the script from ' + url); |
| document.body.appendChild(s); |
| }; |
| </script> |
| </body> |
| </html> |