Skip to content

Commit a943f2b

Browse files
authoredDec 18, 2021
CSP: Improved tokenization (#3276)
1 parent acc0bc0 commit a943f2b

14 files changed

+204
-73
lines changed
 

‎components/prism-csp.js

+67-20
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,73 @@
44
* Reference: https://scotthelme.co.uk/csp-cheat-sheet/
55
*
66
* Supports the following:
7-
* - CSP Level 1
8-
* - CSP Level 2
9-
* - CSP Level 3
7+
* - https://www.w3.org/TR/CSP1/
8+
* - https://www.w3.org/TR/CSP2/
9+
* - https://www.w3.org/TR/CSP3/
1010
*/
1111

12-
Prism.languages.csp = {
13-
'directive': {
14-
pattern: /(^|[^-\da-z])(?:base-uri|block-all-mixed-content|(?:child|connect|default|font|frame|img|manifest|media|object|prefetch|script|style|worker)-src|disown-opener|form-action|frame-(?:ancestors|options)|input-protection(?:-(?:clip|selectors))?|navigate-to|plugin-types|policy-uri|referrer|reflected-xss|report-(?:to|uri)|require-sri-for|sandbox|(?:script|style)-src-(?:attr|elem)|upgrade-insecure-requests)(?=[^-\da-z]|$)/i,
15-
lookbehind: true,
16-
alias: 'keyword'
17-
},
18-
'safe': {
19-
// CSP2 hashes and nonces are base64 values. CSP3 accepts both base64 and base64url values.
20-
// See https://tools.ietf.org/html/rfc4648#section-4
21-
// See https://tools.ietf.org/html/rfc4648#section-5
22-
pattern: /'(?:deny|none|report-sample|self|strict-dynamic|top-only|(?:nonce|sha(?:256|384|512))-[-+/\w=]+)'/i,
23-
alias: 'selector'
24-
},
25-
'unsafe': {
26-
pattern: /(?:'unsafe-(?:allow-redirects|dynamic|eval|hash-attributes|hashed-attributes|hashes|inline)'|\*)/i,
27-
alias: 'function'
12+
(function (Prism) {
13+
14+
/**
15+
* @param {string} source
16+
* @returns {RegExp}
17+
*/
18+
function value(source) {
19+
return RegExp(/([ \t])/.source + '(?:' + source + ')' + /(?=[\s;]|$)/.source, 'i');
2820
}
29-
};
21+
22+
Prism.languages.csp = {
23+
'directive': {
24+
pattern: /(^|[\s;])(?:base-uri|block-all-mixed-content|(?:child|connect|default|font|frame|img|manifest|media|object|prefetch|script|style|worker)-src|disown-opener|form-action|frame-(?:ancestors|options)|input-protection(?:-(?:clip|selectors))?|navigate-to|plugin-types|policy-uri|referrer|reflected-xss|report-(?:to|uri)|require-sri-for|sandbox|(?:script|style)-src-(?:attr|elem)|upgrade-insecure-requests)(?=[\s;]|$)/i,
25+
lookbehind: true,
26+
alias: 'property'
27+
},
28+
'scheme': {
29+
pattern: value(/[a-z][a-z0-9.+-]*:/.source),
30+
lookbehind: true
31+
},
32+
'none': {
33+
pattern: value(/'none'/.source),
34+
lookbehind: true,
35+
alias: 'keyword'
36+
},
37+
'nonce': {
38+
pattern: value(/'nonce-[-+/\w=]+'/.source),
39+
lookbehind: true,
40+
alias: 'number'
41+
},
42+
'hash': {
43+
pattern: value(/'sha(?:256|384|512)-[-+/\w=]+'/.source),
44+
lookbehind: true,
45+
alias: 'number'
46+
},
47+
'host': {
48+
pattern: value(
49+
/[a-z][a-z0-9.+-]*:\/\/[^\s;,']*/.source +
50+
'|' +
51+
/\*[^\s;,']*/.source +
52+
'|' +
53+
/[a-z0-9-]+(?:\.[a-z0-9-]+)+(?::[\d*]+)?(?:\/[^\s;,']*)?/.source
54+
),
55+
lookbehind: true,
56+
alias: 'url',
57+
inside: {
58+
'important': /\*/
59+
}
60+
},
61+
'keyword': [
62+
{
63+
pattern: value(/'unsafe-[a-z-]+'/.source),
64+
lookbehind: true,
65+
alias: 'unsafe'
66+
},
67+
{
68+
pattern: value(/'[a-z-]+'/.source),
69+
lookbehind: true,
70+
alias: 'safe'
71+
},
72+
],
73+
'punctuation': /;/
74+
};
75+
76+
}(Prism));

‎components/prism-csp.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎tests/languages/csp/directive_no_value_feature.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ upgrade-insecure-requests;
44

55
[
66
["directive", "upgrade-insecure-requests"],
7-
";"
7+
["punctuation", ";"]
88
]
99

1010
----------------------------------------------------

‎tests/languages/csp/directive_with_source_expression_feature.test

+14-9
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,26 @@ input-protection tolerance=50; input-protection-clip before=60; input-protection
44

55
[
66
["directive", "input-protection"],
7-
" tolerance=50; ",
7+
" tolerance=50",
8+
["punctuation", ";"],
89
["directive", "input-protection-clip"],
9-
" before=60; ",
10+
" before=60",
11+
["punctuation", ";"],
1012
["directive", "input-protection-selectors"],
11-
" div; ",
13+
" div",
14+
["punctuation", ";"],
1215
["directive", "policy-uri"],
13-
" https://example.com; ",
16+
["host", ["https://example.com"]],
17+
["punctuation", ";"],
1418
["directive", "script-src"],
15-
" example.com; ",
19+
["host", ["example.com"]],
20+
["punctuation", ";"],
1621
["directive", "script-src-attr"],
17-
["safe", "'none'"],
18-
"; ",
22+
["none", "'none'"],
23+
["punctuation", ";"],
1924
["directive", "style-src-elem"],
20-
["safe", "'none'"],
21-
";"
25+
["none", "'none'"],
26+
["punctuation", ";"]
2227
]
2328

2429
----------------------------------------------------

‎tests/languages/csp/hash_feature.test

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
style-src 'sha256-EpOpN/ahUF6jhWShDUdy+NvvtaGcu5F7qM6+x2mfkh4='
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "style-src"],
7+
["hash", "'sha256-EpOpN/ahUF6jhWShDUdy+NvvtaGcu5F7qM6+x2mfkh4='"]
8+
]

‎tests/languages/csp/host_feature.test

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
default-src trusted.com *.trusted.com;
2+
img-src *;
3+
media-src media1.com media2.com;
4+
script-src userscripts.example.com;
5+
frame-ancestors https://alice https://bob;
6+
frame-ancestors https://example.com/;
7+
8+
sandbox allow-scripts;
9+
10+
----------------------------------------------------
11+
12+
[
13+
["directive", "default-src"],
14+
["host", ["trusted.com"]],
15+
["host", [
16+
["important", "*"],
17+
".trusted.com"
18+
]],
19+
["punctuation", ";"],
20+
21+
["directive", "img-src"],
22+
["host", [
23+
["important", "*"]
24+
]],
25+
["punctuation", ";"],
26+
27+
["directive", "media-src"],
28+
["host", ["media1.com"]],
29+
["host", ["media2.com"]],
30+
["punctuation", ";"],
31+
32+
["directive", "script-src"],
33+
["host", ["userscripts.example.com"]],
34+
["punctuation", ";"],
35+
36+
["directive", "frame-ancestors"],
37+
["host", ["https://alice"]],
38+
["host", ["https://bob"]],
39+
["punctuation", ";"],
40+
41+
["directive", "frame-ancestors"],
42+
["host", ["https://example.com/"]],
43+
["punctuation", ";"],
44+
45+
["directive", "sandbox"], " allow-scripts", ["punctuation", ";"]
46+
]

‎tests/languages/csp/issue2661.test

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ default-src-is-a-fake; fake-default-src;
33
----------------------------------------------------
44

55
[
6-
"default-src-is-a-fake; fake-default-src;"
6+
"default-src-is-a-fake",
7+
["punctuation", ";"],
8+
" fake-default-src",
9+
["punctuation", ";"]
710
]
811

912
----------------------------------------------------
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
default-src 'report-sample';
2+
style-src 'self' 'strict-dynamic';
3+
4+
----------------------------------------------------
5+
6+
<span class="token directive property">default-src</span>
7+
<span class="token keyword safe">'report-sample'</span>
8+
<span class="token punctuation">;</span>
9+
<span class="token directive property">style-src</span>
10+
<span class="token keyword safe">'self'</span>
11+
<span class="token keyword safe">'strict-dynamic'</span>
12+
<span class="token punctuation">;</span>
13+
14+
----------------------------------------------------
15+
16+
Checks for source expressions classified as safe.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
navigate-to 'unsafe-allow-redirects';
2+
script-src 'unsafe-dynamic' 'unsafe-eval' 'unsafe-hash-attributes' 'unsafe-hashed-attributes' 'unsafe-hashes' 'unsafe-inline';
3+
4+
----------------------------------------------------
5+
6+
<span class="token directive property">navigate-to</span>
7+
<span class="token keyword unsafe">'unsafe-allow-redirects'</span>
8+
<span class="token punctuation">;</span>
9+
<span class="token directive property">script-src</span>
10+
<span class="token keyword unsafe">'unsafe-dynamic'</span>
11+
<span class="token keyword unsafe">'unsafe-eval'</span>
12+
<span class="token keyword unsafe">'unsafe-hash-attributes'</span>
13+
<span class="token keyword unsafe">'unsafe-hashed-attributes'</span>
14+
<span class="token keyword unsafe">'unsafe-hashes'</span>
15+
<span class="token keyword unsafe">'unsafe-inline'</span>
16+
<span class="token punctuation">;</span>
17+
18+
----------------------------------------------------
19+
20+
Checks for source expressions classified as unsafe.
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
style-src 'nonce-yeah';
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "style-src"],
7+
["nonce", "'nonce-yeah'"],
8+
["punctuation", ";"]
9+
]

‎tests/languages/csp/none_feature.test

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
sandbox 'none'
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "sandbox"],
7+
["none", "'none'"]
8+
]

‎tests/languages/csp/safe_feature.test

-20
This file was deleted.
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
default-src https: 'unsafe-inline' 'unsafe-eval'
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "default-src"],
7+
["scheme", "https:"],
8+
["keyword", "'unsafe-inline'"],
9+
["keyword", "'unsafe-eval'"]
10+
]

‎tests/languages/csp/unsafe_feature.test

-21
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.