From 9dc32aab6ef2bb15357881bc9e1ef66cbe7c2c28 Mon Sep 17 00:00:00 2001 From: Nico Kempe Date: Fri, 22 Dec 2023 14:54:58 +0100 Subject: [PATCH 1/4] Added ignoreXForwardedHost option This option ignores any `x-forwarded-host` headers, which can be used to block SSRF attacks --- CHANGELOG.md | 4 ++++ README.md | 20 ++++++++++++++++++++ index.js | 5 ++++- package.json | 4 ++-- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f12ef06..6a407f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.8.0 (2023-12-22) +Added: + - Added option `ignoreXForwardedHost` to ignore any `X-Forwarded-Host` headers, which can be used to block SSRF attacks + ## 3.7.0 (2023-05-22) Added: - Add Google-InspectionTool to the recognized user agents diff --git a/README.md b/README.md index 951d341..b4620ff 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,26 @@ Option to forward headers from request to prerender. app.use(require('prerender-node').set('forwardHeaders', true)); ``` +### ignoreXForwardedHost + +Option to ignore `X-Forwarded-Host` header. Can be used to block SSRF attacks. + +**Important:** this header is used to preserve the original host header for servers that sit behind a load balancer or internal reverse proxy. If your server does not need this header then it's probably safe to enable this option. Check your environment before enabling this option and make sure to test it first. + +The url that Prerender will get and return the (possibly cached) contents of is created by taking the first available of the following: +- The `host` option, as set with `app.use(require('prerender-node').set('host', 'example.com'));` +- The `X-Forwarded-Host` header, if `ignoreXForwardedHost` is **NOT** set to `true` +- The Host header +Finally the originally requested url path is added to the end. + +The Prerender.io servers will connect to any url you specify at the end of the prerender service URL. This means that if someone visits `https://mysite.com`, and the request is modified with the path `/some/path` and the header `x-forwarded-host` set to `example.com`, Prerender will connect to `https://example.com/some/path`. (You actually don't need to intercept any request, you can just run the whole request directly, e.g. by using Postman.) + +If you set `ignoreXForwardedHost` to `true`, the `X-Forwarded-Host` header will be ignored, effectively blocking these SSRF attacks. + +```js +app.use(require('prerender-node').set('ignoreXForwardedHost', true)); +``` + ### prerenderServerRequestOptions Option to add options to the request sent to the prerender server. diff --git a/index.js b/index.js index d3ad541..98dc96e 100644 --- a/index.js +++ b/index.js @@ -271,7 +271,10 @@ prerender.buildApiUrl = function(req) { if (this.protocol) { protocol = this.protocol; } - var fullUrl = protocol + "://" + (this.host || req.headers['x-forwarded-host'] || req.headers['host']) + req.url; + + // if set, ignore X-Forwarded-Host header to block SSRF attacks + const xforwardedHost = this.ignoreXForwardedHost !== true && req.headers['x-forwarded-host']; + const fullUrl = `${protocol}://${this.host || xforwardedHost || req.headers.host}${req.url}`; return prerenderUrl + forwardSlash + fullUrl; }; diff --git a/package.json b/package.json index f8a2708..6f581ce 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "prerender-node", - "version": "3.7.0", + "version": "3.8.0", "description": "express middleware for serving prerendered javascript-rendered pages for SEO", "author": "Todd Hooper", "license": "MIT", "main": "index.js", "repository": { "type": "git", - "url": "git://github.com/prerender/prerender-node" + "url": "git://github.com/nico014/prerender-node" }, "keywords": [ "angular", From c06161ccc77d09917291b16a2be1aef1817f182c Mon Sep 17 00:00:00 2001 From: Nico Kempe Date: Fri, 22 Dec 2023 15:19:30 +0100 Subject: [PATCH 2/4] bump version to 3.8.0 --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 4ae1d49..fa31582 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prerender-node", - "version": "3.7.0", + "version": "3.8.0", "lockfileVersion": 1, "requires": true, "dependencies": { From b40fda9369c4b79c1ac144e425f360b24ac7dc15 Mon Sep 17 00:00:00 2001 From: Nico Kempe Date: Thu, 28 Dec 2023 11:30:04 +0100 Subject: [PATCH 3/4] Update README spacing --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b4620ff..6102db9 100644 --- a/README.md +++ b/README.md @@ -123,9 +123,9 @@ Option to ignore `X-Forwarded-Host` header. Can be used to block SSRF attacks. **Important:** this header is used to preserve the original host header for servers that sit behind a load balancer or internal reverse proxy. If your server does not need this header then it's probably safe to enable this option. Check your environment before enabling this option and make sure to test it first. The url that Prerender will get and return the (possibly cached) contents of is created by taking the first available of the following: -- The `host` option, as set with `app.use(require('prerender-node').set('host', 'example.com'));` -- The `X-Forwarded-Host` header, if `ignoreXForwardedHost` is **NOT** set to `true` -- The Host header +- The `host` option, as set with `app.use(require('prerender-node').set('host', 'example.com'));` +- The `X-Forwarded-Host` header, if `ignoreXForwardedHost` is **NOT** set to `true` +- The Host header Finally the originally requested url path is added to the end. The Prerender.io servers will connect to any url you specify at the end of the prerender service URL. This means that if someone visits `https://mysite.com`, and the request is modified with the path `/some/path` and the header `x-forwarded-host` set to `example.com`, Prerender will connect to `https://example.com/some/path`. (You actually don't need to intercept any request, you can just run the whole request directly, e.g. by using Postman.) From 861f52b13da97701234e2733ade4a0c120efd4c5 Mon Sep 17 00:00:00 2001 From: Nico Kempe Date: Mon, 22 Jan 2024 16:34:13 +0100 Subject: [PATCH 4/4] Reset package url --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6f581ce..a92f2cb 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "main": "index.js", "repository": { "type": "git", - "url": "git://github.com/nico014/prerender-node" + "url": "git://github.com/prerender/prerender-node" }, "keywords": [ "angular",