-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
125 lines (118 loc) · 5.26 KB
/
index.js
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* jshint esversion: 6 */
/* jslint node: true */
'use strict';
/**
* Middleware to add Content-Security-Policy header http://www.w3.org/TR/CSP/
*
* @option report-only, The Content-Security-Policy-Report-Only header field
* lets servers experiment with policies by monitoring (rather than
* enforcing) a policy.
* @option report-uri, Instructs the browser to POST a reports of policy
* failures to this URI. You can also append -Report-Only to the HTTP
* header name to instruct the browser to only send reports (does not
* block anything).
* @option sandbox, Enables a sandbox for the requested resource similar to the
* iframe sandbox attribute.
*
* @option default-src, The default-src is the default policy for loading
* content such as JavaScript, Images, CSS, Font's, AJAX requests,
* Frames, HTML5 Media
* @option script-src, Defines valid sources of JavaScript.
* @option object-src, Defines valid sources of plugins, eg <object>, <embed>
* or <applet>.
* @option style-src, Defines valid sources of stylesheets.
* @option img-src, Defines valid sources of images.
* @option media-src, Defines valid sources of audio and video, eg HTML5 <audio>, <video> elements.
* @option frame-src, Defines valid sources for loading frames.
* @option font-src, Defines valid sources of fonts.
* @option connect-src, Applies to XMLHttpRequest (AJAX), WebSocket or EventSource. If not allowed the browser emulates a 400 HTTP status code.
* @option child-src, Defines valid sources for web workers and nested browsing contexts loaded using elements such as <frame> and <iframe> (CSP2).
* @option worker-src, Defines valid sources that can be loaded within a Worker, SharedWorker, or ServiceWorker (CSP3).
* @option form-action, Defines valid sources that can be used as a HTML <form> action (CSP2).
* @option frame-ancestors, Defines valid sources for embedding the resource using <frame> <iframe> <object> <embed> <applet>. Setting this directive to 'none' should be roughly equivalent to X-Frame-Options: DENY (CSP2).
* @option plugin-types, Defines valid MIME types for plugins invoked via <object> and <embed>. To load an <applet> you must specify application/x-java-applet (CSP2).
*
*/
module.exports.getCSP = function (options) {
const header = options['report-only'] ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy';
const srcs = ['report-uri', 'sandbox', 'default-src', 'script-src', 'object-src', 'style-src', 'img-src', 'media-src', 'frame-src', 'font-src', 'connect-src', 'child-src', 'worker-src', 'form-action', 'frame-ancestors', 'plugin-types'];
let compiled = '';
srcs.forEach(src => {
const directive = getDirective(options, src);
if (directive) {
compiled += directive + ';';
}
});
return function (req, res, next) {
res.removeHeader('Content-Security-Policy-Report-Only');
res.removeHeader('Content-Security-Policy');
res.setHeader(header, compiled);
next();
};
};
/** */
module.exports.SANDBOX_ALLOW_FORMS = 'allow-forms';
/** */
module.exports.SANDBOX_ALLOW_SCRIPTS = 'allow-scripts';
/** */
module.exports.SANDBOX_ALLOW_SAME = 'allow-same-origin';
/** */
module.exports.SANDBOX_ALLOW_TOP_NAVIGATION = 'allow-top-navigation';
/** Allows loading resources from the same origin (same scheme, host and port). */
module.exports.SRC_SELF = '\'self\'';
/** Prevents loading resources from any source. */
module.exports.SRC_NONE = '\'none\'';
/** Allows use of inline source elements such as style attribute and onclick */
module.exports.SRC_USAFE_INLINE = '\'unsafe-inline\'';
/** Allows unsafe dynamic code evaluation such as JavaScript eval() */
module.exports.SRC_UNSAFE_EVAL = '\'unsafe-eval\'';
/** Allows loading resources via the data scheme (e.g. Base64 encoded images). */
module.exports.SRC_DATA = 'data:';
/** Allows loading resources via a blob. */
module.exports.SRC_BLOB = 'blob:';
/** Wildcard, allows anything. */
module.exports.SRC_ANY = '*';
/** Allows loading resources only over HTTPS on any domain. */
module.exports.SRC_HTTPS = 'https:';
/**
* This policy allows images, scripts, AJAX, and CSS from the same origin, and
* does not allow any other resources to load (eg object, frame, media, etc). It
* is a good starting point for many sites.
*/
module.exports.STARTER_OPTIONS = {
'default-src': module.exports.SRC_NONE,
'script-src': module.exports.SRC_SELF,
'connect-src': module.exports.SRC_SELF,
'img-src': module.exports.SRC_SELF,
'style-src': module.exports.SRC_SELF,
'font-src': module.exports.SRC_SELF,
'child-src': module.exports.SRC_SELF,
'form-action': module.exports.SRC_SELF,
'frame-ancestors': module.exports.SRC_SELF,
'plugin-types': module.exports.SRC_NONE
};
/**
* Helper function to compile one directive. handles strings and arrays.
*
* @param options
* all options
* @param name
* name of the one to compile
* @returns compilation of named option
*/
function getDirective (options, name) {
if (!options[name]) {
return null;
}
if (typeof options[name] === 'string') {
return name + ' ' + options[name];
}
if (Array.isArray(options[name])) {
let result = name + ' ';
options[name].forEach(value => {
result += value + ' ';
});
return result;
}
return null;
}