Skip to content

Commit b08cae5

Browse files
papandreouGolmote
authored andcommitted
Add support for highlighting CSP, HSTS, and HPKP (#1275)
* Add CSP support. * Add HPKP support. * Add HSTS support. * Updates based on feedback. * Updates based on feedback. * Updates based on feedback. * Updates based on feedback. * Updates based on feedback. * Updates based on feedback. * Updates based on Feedback. * Fix parentheses. * List csp, hpkp, and hsts in components.js * Add missing base64 chars to 'nonce-...' and 'sha-...' source expressions * Add support for 'sha384-...' and 'sha512-...' source expressions * Add tests and examples for csp * Add tests and examples for hsts * Add tests and examples for hpkp * hpkp: Include the sha256 hash in the directive itself Prevent the numbers in the base64 string from being classified as "safe" or "unsafe". * Rebuild the minified csp and hpkp components * Rebuild the "Show Language" plugin as well * Fix copy/paste error in test description
1 parent 3da238f commit b08cae5

23 files changed

+261
-2
lines changed

components.js

+12
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ var components = {
161161
"require": "ruby",
162162
"owner": "MakeNowJust"
163163
},
164+
"csp": {
165+
"title": "Content-Security-Policy",
166+
"owner": "ScottHelme"
167+
},
164168
"css-extras": {
165169
"title": "CSS Extras",
166170
"require": "css",
@@ -269,6 +273,14 @@ var components = {
269273
"title": "HTTP",
270274
"owner": "danielgtaylor"
271275
},
276+
"hpkp": {
277+
"title": "HTTP Public-Key-Pins",
278+
"owner": "ScottHelme"
279+
},
280+
"hsts": {
281+
"title": "HTTP Strict-Transport-Security",
282+
"owner": "ScottHelme"
283+
},
272284
"ichigojam": {
273285
"title": "IchigoJam",
274286
"owner": "BlueCocoa"

components/prism-csp.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Original by Scott Helme.
3+
*
4+
* Reference: https://scotthelme.co.uk/csp-cheat-sheet/
5+
*
6+
* Supports the following:
7+
* - CSP Level 1
8+
* - CSP Level 2
9+
* - CSP Level 3
10+
*/
11+
12+
Prism.languages.csp = {
13+
'directive': {
14+
pattern: /\b(?:(?:base-uri|form-action|frame-ancestors|plugin-types|referrer|reflected-xss|report-to|report-uri|require-sri-for|sandbox) |(?:block-all-mixed-content|disown-opener|upgrade-insecure-requests)(?: |;)|(?:child|connect|default|font|frame|img|manifest|media|object|script|style|worker)-src )/i,
15+
alias: 'keyword'
16+
},
17+
'safe': {
18+
pattern: /'(?:self|none|strict-dynamic|(?:nonce-|sha(?:256|384|512)-)[a-zA-Z0-9+=/]+)'/,
19+
alias: 'selector'
20+
},
21+
'unsafe': {
22+
pattern: /(?:'unsafe-inline'|'unsafe-eval'|'unsafe-hashed-attributes'|\*)/,
23+
alias: 'function'
24+
}
25+
};

components/prism-csp.min.js

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

components/prism-hpkp.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Original by Scott Helme.
3+
*
4+
* Reference: https://scotthelme.co.uk/hpkp-cheat-sheet/
5+
*/
6+
7+
Prism.languages.hpkp = {
8+
'directive': {
9+
pattern: /\b(?:(?:includeSubDomains|preload|strict)(?: |;)|pin-sha256="[a-zA-Z0-9+=/]+"|(?:max-age|report-uri)=|report-to )/,
10+
alias: 'keyword'
11+
},
12+
'safe': {
13+
pattern: /[0-9]{7,}/,
14+
alias: 'selector'
15+
},
16+
'unsafe': {
17+
pattern: /[0-9]{0,6}/,
18+
alias: 'function'
19+
}
20+
};

components/prism-hpkp.min.js

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

components/prism-hsts.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Original by Scott Helme.
3+
*
4+
* Reference: https://scotthelme.co.uk/hsts-cheat-sheet/
5+
*/
6+
7+
Prism.languages.hsts = {
8+
'directive': {
9+
pattern: /\b(?:max-age=|includeSubDomains|preload)/,
10+
alias: 'keyword'
11+
},
12+
'safe': {
13+
pattern: /[0-9]{8,}/,
14+
alias: 'selector'
15+
},
16+
'unsafe': {
17+
pattern: /[0-9]{0,7}/,
18+
alias: 'function'
19+
}
20+
};

components/prism-hsts.min.js

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

examples/prism-csp.html

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h1>HTTP Content-Security-Policy header value</h1>
2+
<p>To use this language, use the class "language-csp".</p>
3+
4+
<h2>A complete policy</h2>
5+
<pre><code>default-src 'none';
6+
script-src my.cdn.com;
7+
img-src 'self' data:;
8+
child-src 'self' data: ms-appx-web:;
9+
block-all-mixed-content;
10+
report-uri https://my-reports.com/submit;
11+
</code></pre>
12+
13+
<h2>An policy with unsafe source expressions</h2>
14+
<pre><code>script-src 'self' 'unsafe-eval' 'unsafe-inline';
15+
style-src 'unsafe-inline' 'unsafe-hashed-attributes' 'self';
16+
</code></pre>

examples/prism-hpkp.html

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<h1>HTTP Public-Key-Pins header value</h1>
2+
<p>To use this language, use the class "language-hpkp".</p>
3+
4+
<h2>Pin for one year with report-uri</h2>
5+
<pre><code>pin-sha256="EpOpN/ahUF6jhWShDUdy+NvvtaGcu5F7qM6+x2mfkh4=";
6+
max-age=31536000;
7+
includeSubDomains;
8+
report-uri="https://my-reports.com/submit"
9+
</code></pre>
10+
11+
<h2>Pin for a short time (considered unsafe)</h2>
12+
<pre><code>pin-sha256="EpOpN/ahUF6jhWShDUdy+NvvtaGcu5F7qM6+x2mfkh4=";
13+
max-age=123
14+
</code></pre>

examples/prism-hsts.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<h1>HTTP Strict-Transport-Security header value</h1>
2+
<p>To use this language, use the class "language-hsts".</p>
3+
4+
<h2>Policy with far-future max-age</h2>
5+
<pre><code>max-age=31536000</code></pre>
6+
7+
<h2>Policy with near-future max-age, considered unsafe</h2>
8+
<pre><code>max-age=123</code></pre>
9+
10+
<h2>Policy with extra directives</h2>
11+
<pre><code>max-age=31536000; includeSubdomains; preload</code></pre>

plugins/show-language/prism-show-language.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ if (!Prism.plugins.toolbar) {
1111
}
1212

1313
// The languages map is built automatically with gulp
14-
var Languages = /*languages_placeholder[*/{"html":"HTML","xml":"XML","svg":"SVG","mathml":"MathML","css":"CSS","clike":"C-like","javascript":"JavaScript","abap":"ABAP","actionscript":"ActionScript","apacheconf":"Apache Configuration","apl":"APL","applescript":"AppleScript","asciidoc":"AsciiDoc","asm6502":"6502 Assembly","aspnet":"ASP.NET (C#)","autohotkey":"AutoHotkey","autoit":"AutoIt","basic":"BASIC","csharp":"C#","cpp":"C++","coffeescript":"CoffeeScript","css-extras":"CSS Extras","django":"Django/Jinja2","fsharp":"F#","glsl":"GLSL","graphql":"GraphQL","http":"HTTP","ichigojam":"IchigoJam","inform7":"Inform 7","json":"JSON","latex":"LaTeX","livescript":"LiveScript","lolcode":"LOLCODE","matlab":"MATLAB","mel":"MEL","n4js":"N4JS","nasm":"NASM","nginx":"nginx","nsis":"NSIS","objectivec":"Objective-C","ocaml":"OCaml","opencl":"OpenCL","parigp":"PARI/GP","php":"PHP","php-extras":"PHP Extras","powershell":"PowerShell","properties":".properties","protobuf":"Protocol Buffers","jsx":"React JSX","renpy":"Ren'py","rest":"reST (reStructuredText)","sas":"SAS","sass":"Sass (Sass)","scss":"Sass (Scss)","sql":"SQL","typescript":"TypeScript","vbnet":"VB.Net","vhdl":"VHDL","vim":"vim","wiki":"Wiki markup","xojo":"Xojo (REALbasic)","yaml":"YAML"}/*]*/;
14+
var Languages = /*languages_placeholder[*/{"html":"HTML","xml":"XML","svg":"SVG","mathml":"MathML","css":"CSS","clike":"C-like","javascript":"JavaScript","abap":"ABAP","actionscript":"ActionScript","apacheconf":"Apache Configuration","apl":"APL","applescript":"AppleScript","asciidoc":"AsciiDoc","asm6502":"6502 Assembly","aspnet":"ASP.NET (C#)","autohotkey":"AutoHotkey","autoit":"AutoIt","basic":"BASIC","csharp":"C#","cpp":"C++","coffeescript":"CoffeeScript","csp":"Content-Security-Policy","css-extras":"CSS Extras","django":"Django/Jinja2","fsharp":"F#","glsl":"GLSL","graphql":"GraphQL","http":"HTTP","hpkp":"HTTP Public-Key-Pins","hsts":"HTTP Strict-Transport-Security","ichigojam":"IchigoJam","inform7":"Inform 7","json":"JSON","latex":"LaTeX","livescript":"LiveScript","lolcode":"LOLCODE","matlab":"MATLAB","mel":"MEL","n4js":"N4JS","nasm":"NASM","nginx":"nginx","nsis":"NSIS","objectivec":"Objective-C","ocaml":"OCaml","opencl":"OpenCL","parigp":"PARI/GP","php":"PHP","php-extras":"PHP Extras","powershell":"PowerShell","properties":".properties","protobuf":"Protocol Buffers","jsx":"React JSX","renpy":"Ren'py","rest":"reST (reStructuredText)","sas":"SAS","sass":"Sass (Sass)","scss":"Sass (Scss)","sql":"SQL","typescript":"TypeScript","vbnet":"VB.Net","vhdl":"VHDL","vim":"vim","wiki":"Wiki markup","xojo":"Xojo (REALbasic)","yaml":"YAML"}/*]*/;
1515
Prism.plugins.toolbar.registerButton('show-language', function(env) {
1616
var pre = env.element.parentNode;
1717
if (!pre || !/pre/i.test(pre.nodeName)) {

plugins/show-language/prism-show-language.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
upgrade-insecure-requests;
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "upgrade-insecure-requests;"]
7+
]
8+
9+
----------------------------------------------------
10+
11+
Checks for a "void" CSP directive followed by semicolon.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
script-src example.com;
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "script-src "],
7+
"example.com;"
8+
]
9+
10+
----------------------------------------------------
11+
12+
Checks for CSP directive followed by a source expression.

tests/languages/csp/safe_feature.test

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
default-src 'none'; style-src 'self' 'strict-dynamic' 'nonce-yeah' 'sha256-EpOpN/ahUF6jhWShDUdy+NvvtaGcu5F7qM6+x2mfkh4=';
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "default-src "],
7+
["safe", "'none'"],
8+
"; ",
9+
["directive", "style-src "],
10+
["safe", "'self'"],
11+
["safe", "'strict-dynamic'"],
12+
["safe", "'nonce-yeah'"],
13+
["safe", "'sha256-EpOpN/ahUF6jhWShDUdy+NvvtaGcu5F7qM6+x2mfkh4='"],
14+
";"
15+
]
16+
17+
----------------------------------------------------
18+
19+
Checks for source expressions classified as safe.
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
script-src 'unsafe-inline' 'unsafe-eval' 'unsafe-hashed-attributes';
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "script-src "],
7+
["unsafe", "'unsafe-inline'"],
8+
["unsafe", "'unsafe-eval'"],
9+
["unsafe", "'unsafe-hashed-attributes'"],
10+
";"
11+
]
12+
13+
----------------------------------------------------
14+
15+
Checks for source expressions classified as unsafe.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
max-age=31536000
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "max-age="],
7+
["safe", "31536000"]
8+
]
9+
10+
----------------------------------------------------
11+
12+
Checks for HPKP with a "safe" max-age.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
pin-sha256="EpOpN/ahUF6jhWShDUdy+NvvtaGcu5F7qM6+x2mfkh4="
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "pin-sha256=\"EpOpN/ahUF6jhWShDUdy+NvvtaGcu5F7qM6+x2mfkh4=\""]
7+
]
8+
9+
----------------------------------------------------
10+
11+
Checks for HPKP with a sha256 pin.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
max-age=123
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "max-age="],
7+
["unsafe", "123"]
8+
]
9+
10+
----------------------------------------------------
11+
12+
Checks for HPKP with an "unsafe" max-age.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
includeSubDomains
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "includeSubDomains"]
7+
]
8+
9+
----------------------------------------------------
10+
11+
Checks for HSTS with the includeSubDomains directive.
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
preload
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "preload"]
7+
]
8+
9+
----------------------------------------------------
10+
11+
Checks for HSTS with the preload directive.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
max-age=31536000
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "max-age="],
7+
["safe", "31536000"]
8+
]
9+
10+
----------------------------------------------------
11+
12+
Checks for HSTS with a "safe" max-age.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
max-age=123
2+
3+
----------------------------------------------------
4+
5+
[
6+
["directive", "max-age="],
7+
["unsafe", "123"]
8+
]
9+
10+
----------------------------------------------------
11+
12+
Checks for HSTS with an "unsafe" max-age.

0 commit comments

Comments
 (0)