From 6d8ee1cd81927802238c24808e7d5539a54dad87 Mon Sep 17 00:00:00 2001 From: lutra <49721741+lutra@users.noreply.github.com> Date: Wed, 28 Aug 2019 15:16:35 +0200 Subject: [PATCH 1/2] Add target whitelisting Define a regular expression to environment variable CORSANYWHERE_TARGET_WHITELIST to permit access to targets only. --- lib/cors-anywhere.js | 7 +++++++ lib/target-whitelist.js | 26 ++++++++++++++++++++++++++ server.js | 4 ++++ 3 files changed, 37 insertions(+) create mode 100644 lib/target-whitelist.js diff --git a/lib/cors-anywhere.js b/lib/cors-anywhere.js index bedfc47b..ec5fbf95 100644 --- a/lib/cors-anywhere.js +++ b/lib/cors-anywhere.js @@ -250,6 +250,7 @@ function getHandler(options, proxy) { originWhitelist: [], // If non-empty, requests not from an origin in this list will be blocked. checkRateLimit: null, // Function that may enforce a rate-limit by returning a non-empty string. redirectSameOrigin: false, // Redirect the client to the requested URL for same-origin requests. + checkTargetWhitelisted: null, requireHeader: null, // Require a header to be set? removeHeaders: [], // Strip these request headers. setHeaders: {}, // Set these request headers. @@ -364,6 +365,12 @@ function getHandler(options, proxy) { return; } + if (corsAnywhere.checkTargetWhitelisted && !corsAnywhere.checkTargetWhitelisted(location)) { + res.writeHead(403, 'Forbidden', cors_headers); + res.end('You are not permitted to access the location "' + location.href + '".'); + return; + } + var isRequestedOverHttps = req.connection.encrypted || /^\s*https/.test(req.headers['x-forwarded-proto']); var proxyBaseUrl = (isRequestedOverHttps ? 'https://' : 'http://') + req.headers.host; diff --git a/lib/target-whitelist.js b/lib/target-whitelist.js new file mode 100644 index 00000000..711f8cb2 --- /dev/null +++ b/lib/target-whitelist.js @@ -0,0 +1,26 @@ +'use strict'; + +module.exports = function createTargetWhitelistChecker(targetWhitelist) { + // Configure targets to access. Use the environment variable CORSANYWHERE_TARGET_WHITELIST with a regular expression. + // + // Example: + // ^https?:\/\/duckduckgo\.com + // To access https://duckduckgo.com and all its sub-paths (such as https://duckduckgo.com/?q=looking+for+node.js+proxy) + if (!targetWhitelist || targetWhitelist.length === 0) { + // Permitted by default + return function permitted() { + return true; + }; + } + + // Test if regular expression is valid + var targetWhitelistPattern = new RegExp(targetWhitelist); + + return function permitted(origin) { + if (targetWhitelistPattern && targetWhitelistPattern.test(origin.href)) { + return true; + } + + return false; + }; +}; diff --git a/server.js b/server.js index fb3f84d3..2749ad61 100644 --- a/server.js +++ b/server.js @@ -19,12 +19,16 @@ function parseEnvList(env) { // Set up rate-limiting to avoid abuse of the public CORS Anywhere server. var checkRateLimit = require('./lib/rate-limit')(process.env.CORSANYWHERE_RATELIMIT); +// Regular expression, which targets are allowed to access +var checkTargetWhitelisted = require('./lib/target-whitelist')(process.env.CORSANYWHERE_TARGET_WHITELIST); + var cors_proxy = require('./lib/cors-anywhere'); cors_proxy.createServer({ originBlacklist: originBlacklist, originWhitelist: originWhitelist, requireHeader: ['origin', 'x-requested-with'], checkRateLimit: checkRateLimit, + checkTargetWhitelisted: checkTargetWhitelisted, removeHeaders: [ 'cookie', 'cookie2', From 86a5777135eda5348ba6a2ce63355fbbc81b5a81 Mon Sep 17 00:00:00 2001 From: lutra <49721741+lutra@users.noreply.github.com> Date: Wed, 28 Aug 2019 15:16:45 +0200 Subject: [PATCH 2/2] Add Dockerfile --- Dockerfile | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..8f54ece4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM node:lts-alpine + +RUN mkdir -p /app +WORKDIR /app + +COPY package.json server.js /app/ +COPY lib /app/lib/ +RUN npm install + +ENV CORSANYWHERE_TARGET_WHITELIST "^https?:\/\/duckduckgo\.com" + +CMD [ "node", "/app/server.js" ] +EXPOSE 8080