slower 1.1.11 → 1.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/router.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const http = require('http');
2
2
  const fs = require('fs');
3
- const { noop, slugify, isSparseEqual, last, renderDynamicHTML, setSocketLocals } = require('./utils');
3
+ const { noop, slugify, isSparseEqual, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders } = require('./utils');
4
4
 
5
5
  class Route {
6
6
  constructor (path, type, callback) {
@@ -33,6 +33,7 @@ class SlowerRouter {
33
33
  }
34
34
 
35
35
  constructor () {
36
+ this.strictHeaders = false;
36
37
  this.routes = [];
37
38
  this.middleware = [noop];
38
39
  this.fallback = noop;
@@ -40,6 +41,20 @@ class SlowerRouter {
40
41
  this.blockedMethodCallback = noop;
41
42
  }
42
43
 
44
+ enableStrictHeaders () {
45
+ // This activates the responses with many security-related response headers.
46
+ // It is not enabled by default, as some header are very restrictive
47
+ this.strictHeaders = true;
48
+ return this;
49
+ }
50
+
51
+ disableStrictHeaders () {
52
+ // This deactivates the responses with many security-related response headers.
53
+ // It is not enabled by default, as some headers are very restrictive
54
+ this.strictHeaders = false;
55
+ return this;
56
+ }
57
+
43
58
  /**
44
59
  * Defines a route for a determined request method
45
60
  * @category Router
@@ -291,6 +306,10 @@ class SlowerRouter {
291
306
  try {
292
307
  // Sets local req.session object
293
308
  setSocketLocals(req);
309
+ // Sets security headers in req.headers
310
+ // This is set before custom callbacks are applies
311
+ // so it is possible to override all of the headers
312
+ if (!!this.strictHeaders) setSocketSecurityHeaders(req);
294
313
  // Runs all middlewares
295
314
  for (let i = 0; i < middle.length; i++) { middle[i](req, res); }
296
315
  // Only respond to allowed methods with callbacks, else, use the default empty response.
package/lib/utils.js CHANGED
@@ -86,6 +86,59 @@ const setSocketLocals = (socket) => {
86
86
  return socket;
87
87
  }
88
88
 
89
+ const setSocketSecurityHeaders = (req) => {
90
+ // This should be set in a regular website:
91
+ // Forces the use of HTTPS for a long time, including subDomains - and prevent MitM attacks
92
+ // Does not work in servers that don't allow HTTPS (like this one)
93
+ // req.setHeader('Strict-Transport-Security', ['max-age=31536000', 'includeSubDomains']); // Only works on HTTPS
94
+
95
+ // This blocks requests with MIME type different from style/css and */script
96
+ // TODO test this - probably gonna break the server, as MIMEs are not overriden here
97
+ // req.setHeader('X-Content-Type-Options', 'nosniff');
98
+
99
+ // This deines the main security policy - Usually, when using a website,
100
+ // this should be highly customized, but, for simple sites, it can be leaved like that:
101
+ req.setHeader('Content-Security-Policy', [
102
+ 'default-src=none',
103
+ 'script-src=self',
104
+ 'connect-src=self',
105
+ 'img-src=self',
106
+ 'style-src=self',
107
+ 'frame-ancestors=none',
108
+ 'form-action=self',
109
+ // 'upgrade-insecure-requests' // Only works on HTTPS
110
+ ]);
111
+ // Isolates the browsing context exclusively to same-origin documents.
112
+ // Cross-origin documents are not loaded in the same browsing context.
113
+ req.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
114
+ // The HTTP Cross-Origin-Resource-Policy response header conveys a desire
115
+ // that the browser blocks no-cors cross-origin/cross-site requests to the given resource.
116
+ req.setHeader('Cross-Origin-Resource-Policy', 'same-site');
117
+ // A new HTTP response header that instructs the browser
118
+ // to prevent synchronous scripting access between same-site cross-origin pages.
119
+ req.setHeader('Origin-Agent-Cluster', '?1');
120
+ // Blocks information about the website when sending
121
+ // local requests or redirections to other sites
122
+ req.setHeader('Referrer-Policy', 'no-referrer');
123
+ // Enabling this makes all URLs in a page (even the cross domain ones)
124
+ // to be prefetched - This is dangerouns in terms of DNS queries
125
+ req.setHeader('X-DNS-Prefetch-Control', 'off');
126
+ // A legacy header, just for IE, and is highly dangerous
127
+ // Not setting this as disabled can cause malicious
128
+ // HTML+JS code to be loaded in the wrong context
129
+ req.setHeader('X-Download-Options', 'noopen');
130
+ // Blocks attempts to display the website as an IFrame
131
+ // If another website tries to display this website as a frame,
132
+ // this header will block it
133
+ req.setHeader('X-Frame-Options', 'DENY');
134
+ // Set the unnecessary XSS-Protection legacy header to disabled
135
+ // This header increases the number of vulnerabilities, and is used only in IE
136
+ req.setHeader('X-XSS-Protection', 0);
137
+ // Remove X-Powered-By - This header allows attackers to
138
+ // gather information about the application engine
139
+ if (req.hasHeader('X-Powered-By')) req.removeHeader('X-Powered-By');
140
+ }
141
+
89
142
  const toBool = [() => true, () => false];
90
143
 
91
- module.exports = { noop, slugify, isSparseEqual, toBool, last, renderDynamicHTML, setSocketLocals };
144
+ module.exports = { noop, slugify, isSparseEqual, toBool, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slower",
3
- "version": "1.1.11",
3
+ "version": "1.1.12",
4
4
  "description": "A package for simple HTTP server routing.",
5
5
  "main": "index.js",
6
6
  "directories": {
package/readme.md CHANGED
@@ -63,4 +63,24 @@ a socket will receive the modified socket instead.
63
63
  during the lifetime of a single connection. Useful for keeping short-life local variables.
64
64
 
65
65
  - In HTTP ```http.IncomingMessage``` instances, the 'socket' instance is found over 'request'.
66
- So, considering the common callback of ```(req, res)```, the session container will be ```req.session```
66
+ So, considering the common callback of ```(req, res)```, the session container will be ```req.session```
67
+
68
+ ### API security headers implementation:
69
+ - It is possible to enforce a higher set of security headers on responses
70
+ without having to set them manually. The API 'enableStrictHeaders' and 'disableStrictHeaders'
71
+ methods do exacly that. The strict headers are disabled by default, as some resources are too strict,
72
+ but it is also possible to enable them all, and then set a middleware to override any header.
73
+ - Headers set by 'enableStrictHeaders':
74
+ Content-Security-Policy: default-src=none; script-src=self; connect-src=self; img-src=self;
75
+ style-src=self; frame-ancestors=none; form-action=self;
76
+ Cross-Origin-Opener-Policy: same-origin
77
+ Cross-Origin-Resource-Policy: same-site
78
+ Origin-Agent-Cluster: ?1
79
+ Referrer-Policy: no-referrer
80
+ Strict-Transport-Security: max-age=31536000; includeSubDomains // temporarily disabled for maintenance
81
+ X-Content-Type-Options: nosniff // temporarily disabled for maintenance
82
+ X-DNS-Prefetch-Control: off
83
+ X-Download-Options: noopen
84
+ X-Frame-Options: DENY
85
+ X-Powered-By: (This header is removed if a response includes it)
86
+ X-XSS-Protection: 0