pixl-server-web 2.0.2 → 2.0.4

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/README.md CHANGED
@@ -441,6 +441,28 @@ This example would reject all incoming IP addresses from Apple and AT&T (who own
441
441
 
442
442
  When a new incoming connection is established, the socket IP is immediately checked against the blacklist, and if matched, the socket is "hard closed". This is an early detection and rejection, before the HTTP request even comes in. In this case a HTTP response isn't sent back (as the socket is simply slammed shut). However, if you are using a load balancer or proxy, the user's true IP address might not be known until later on in the request cycle, once the HTTP headers are read in. At that point all the user's IPs are checked against the blacklist again, and if any of them match, a `HTTP 403 Forbidden` response is sent back.
443
443
 
444
+ ## http_allow_hosts
445
+
446
+ The `http_allow_hosts` property allows you to specify a list of hosts to allow on incoming requests. Specifically, this matches the incoming HTTP `Host` request header, and the value must match at least one entry in the array (case-insensitive). For example, if you are hosting your application behind a domain name, you may want to restrict incoming requests so that they must explicitly point to your domain name (and disallow requests to the IP address). Here is how to set this up:
447
+
448
+ ```json
449
+ "http_allow_hosts": ["mydomain.com"]
450
+ ```
451
+
452
+ In the above example, only requests to `mydomain.com` would be allowed. All other domains or IP addresses in the URL would be rejected with a `HTTP 403 Forbidden` error. Include multiple entries in the array for things like subdomains:
453
+
454
+ ```json
455
+ "http_allow_hosts": ["mydomain.com", "www.mydomain.com"]
456
+ ```
457
+
458
+ Note that if your users have to specify a port number in the URL, this must be specified in the `http_allow_hosts` array as well (it matches the `Host` request header exactly). So for example, if you are hosting an app on a non-standard port number, but you want to restrict the host, include the port like this:
459
+
460
+ ```json
461
+ "http_allow_hosts": ["mydomain.com:3000"]
462
+ ```
463
+
464
+ If the `http_allow_hosts` array is empty or omitted entirely, all hosts are allowed. This is the default behavior.
465
+
444
466
  ## http_rewrites
445
467
 
446
468
  If you need to rewrite certain incoming URLs on-the-fly, you can define rules in the `http_rewrites` object. The basic format is as follows: keys are regular expressions matched on incoming URI paths, and the values are the substitution strings to use as replacements. Here is a simple example:
@@ -789,6 +811,19 @@ Note that these are matched using logical OR, so only one of them needs to match
789
811
 
790
812
  This sets the idle socket timeout for all incoming HTTPS requests. If omitted, the Node.js default is 2 minutes. Please specify your value in seconds.
791
813
 
814
+ ## https_bind_address
815
+
816
+ Optionally specify an exact local IP address to bind the HTTPS listener to. By default this uses the value of [http_bind_address](#http_bind_address), but you can bind them differently using this property. Example:
817
+
818
+ ```json
819
+ {
820
+ "http_bind_address": "127.0.0.1",
821
+ "https_bind_address": "0.0.0.0"
822
+ }
823
+ ```
824
+
825
+ This example would cause the server to only listen on localhost for plain HTTP traffic, but listen on *all* network interfaces for HTTPS traffic.
826
+
792
827
  # Custom URI Handlers
793
828
 
794
829
  You can attach your own handler methods for intercepting and responding to certain incoming URIs. So for example, instead of the URI `/api/add_user` looking for a static file on disk, you can have the web server invoke your own function for handling it, and sending a custom response.
package/lib/http.js CHANGED
@@ -208,7 +208,8 @@ module.exports = class HTTP {
208
208
 
209
209
  // do not try to write to socket if already closed
210
210
  if ((err.code != 'ECONNRESET') && socket.writable) {
211
- socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
211
+ if (err.code == 'HPE_INVALID_METHOD') socket.destroy();
212
+ else socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
212
213
  }
213
214
  socket._pixl_data.aborted = true;
214
215
 
package/lib/https.js CHANGED
@@ -206,7 +206,8 @@ module.exports = class HTTP2 {
206
206
 
207
207
  // do not try to write to socket if already closed
208
208
  if ((err.code != 'ECONNRESET') && socket.writable) {
209
- socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
209
+ if (err.code == 'HPE_INVALID_METHOD') socket.destroy();
210
+ else socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
210
211
  }
211
212
  socket._pixl_data.aborted = true;
212
213
 
package/lib/request.js CHANGED
@@ -71,6 +71,24 @@ module.exports = class Request {
71
71
  return;
72
72
  }
73
73
 
74
+ // custom host allow list
75
+ if (this.allowHosts.length && !this.allowHosts.includes( ('' + request.headers['host']).toLowerCase() )) {
76
+ this.logError(403, "Forbidden: Host not allowed: " + (request.headers['host'] || 'n/a'), {
77
+ id: args.id,
78
+ host: request.headers['host'] || '',
79
+ useragent: request.headers['user-agent'] || '',
80
+ referrer: request.headers['referer'] || '',
81
+ cookie: request.headers['cookie'] || '',
82
+ url: this.getSelfURL(request, request.url) || request.url
83
+ });
84
+ this.sendHTTPResponse( args,
85
+ "403 Forbidden",
86
+ { 'Content-Type': "text/html" },
87
+ "403 Forbidden\n"
88
+ );
89
+ return;
90
+ }
91
+
74
92
  // allow special URIs to skip the line
75
93
  if (this.queueSkipMatch && request.url.match(this.queueSkipMatch)) {
76
94
  this.logDebug(8, "Bumping request to front of queue: " + request.url);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixl-server-web",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "A web server component for the pixl-server framework.",
5
5
  "author": "Joseph Huckaby <jhuckaby@gmail.com>",
6
6
  "homepage": "https://github.com/jhuckaby/pixl-server-web",
package/web_server.js CHANGED
@@ -47,6 +47,7 @@ module.exports = Class({
47
47
  "http_enable_brotli": false,
48
48
  "http_default_acl": ['127.0.0.1', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '::1/128', 'fd00::/8', '169.254.0.0/16', 'fe80::/10'],
49
49
  "http_blacklist": [],
50
+ "http_allow_hosts": [],
50
51
  "http_log_requests": false,
51
52
  "http_log_request_details": false,
52
53
  "http_log_body_max": 32768,
@@ -243,6 +244,9 @@ class WebServer extends Component {
243
244
  this.redirects.push(redirect);
244
245
  }
245
246
  }
247
+
248
+ // custom host list
249
+ this.allowHosts = (this.config.get('http_allow_hosts') || []).map( function(host) { return host.toLowerCase(); } );
246
250
  }
247
251
 
248
252
  startAll(callback) {