File: hooks-scheme-allowlist.html

package info (click to toggle)
node-dompurify 3.3.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,956 kB
  • sloc: javascript: 11,284; makefile: 2; sh: 2
file content (78 lines) | stat: -rw-r--r-- 3,874 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<!doctype html>
<html>
    <head>
        <script src="../dist/purify.js"></script>
    </head>
    <body>
        <!-- Our DIV to receive content -->
        <div id="sanitized"></div>

        <!-- Now let's sanitize that content -->
        <script>
            'use strict';
            
            // Specify dirty HTML
            const dirty = `
                <a href="foo:?a">INSECURE</a>
                <a href="ftp://abc.de?a">SECURE</a>
                <a href="https://abc.de?a">SECURE</a>
                <a href="?a">SECURE</a>
                <svg><a href="ms-appx://some/app/test.html"><circle r=40 fill=red></a></svg>
                <svg><a href="http://benign.com/"><circle r=40 fill=green></a></svg>
                <svg><a href="#123"><circle r=40 fill=green></a></svg>
                <form action="?form"><input type="submit" value="safe"></form>
                <form action="bingweather:?lat=1&long=2"><input type="submit" value="unsafe"></form>
                <img src="404" width="200" height="200" usemap="#test">
                <map name="test"><area href="skype://123456?call" shape="rect" coords="0,0,200,200"></area></map>
                <img src="404" width="200" height="200" usemap="#test">
                <map name="test"><area href="http://test.com/" shape="rect" coords="0,0,200,200"></area></map>
                <math href="http://test.com/">SECURE</math>
                <math href="calculator:">INSECURE</math>
                <math><mi target="xxx" href="http://test.com/">SECURE</mi></math>
                <math><mi href="javascript:alert(1)">INSECURE</mi></math>
                <math><mi target="xxx" href="aim:1111111?call">INSECURE</mi></math>
                <svg xmlns:xlink="http://www.w3.org/1999/xlink"><a xlink:href="https://test.com/"><circle r=40 fill=green></a></svg>
                <svg xmlns:xlink="http://www.w3.org/1999/xlink"><a xlink:href="telnet:1.1.1.1"><circle r=40 fill=red></a></svg>
                <svg xmlns:xlink="http://www.w3.org/1999/xlink"><a xlink:href="?secure"><circle r=40 fill=green></a></svg>
            `;
            
            // Allowed URI schemes
            const allowlist = ['http', 'https', 'ftp'];
            
            // Build fitting regex
            const regex = RegExp(`^(${allowlist.join('|')}):`, 'im');
            
            // Add a hook to enforce URI scheme allow-list
            DOMPurify.addHook('afterSanitizeAttributes', node => {
                // Build an anchor to map URLs to
                const anchor = document.createElement('a');
            
                // Check all href attributes for validity
                if (node.hasAttribute('href')) {
                    anchor.href = node.getAttribute('href');
                    if (anchor.protocol && !anchor.protocol.match(regex)) {
                        node.removeAttribute('href');
                    }
                }
                // Check all action attributes for validity
                if (node.hasAttribute('action')) {
                    anchor.href = node.getAttribute('action');
                    if (anchor.protocol && !anchor.protocol.match(regex)) {
                        node.removeAttribute('action');
                    }
                }
                // Check all xlink:href attributes for validity
                if (node.hasAttribute('xlink:href')) {
                    anchor.href = node.getAttribute('xlink:href');
                    if (anchor.protocol && !anchor.protocol.match(regex)) {
                        node.removeAttribute('xlink:href');
                    }
                }
            });
            
            // Clean HTML string and write into our DIV
            const clean = DOMPurify.sanitize(dirty);
            document.getElementById('sanitized').innerHTML = clean;
        </script>
    </body>
</html>