From 3cf886d1d1c137acd80d32de4b7a6b1e750e27e5 Mon Sep 17 00:00:00 2001 From: Brian Hoffman Date: Fri, 3 Jun 2016 09:30:55 -0400 Subject: [PATCH 1/2] [SECURITY] Update application to support https endpoints This is a critical security fix for potential MITM attacks against http endpoints. An attacker could hijack the nuts server responses and force users to download vulnerable software unknowingly. This pull request enables an optional (but recommended) https endpoint so that applications will be protected when retrieving updates. --- bin/web.js | 23 ++++++++++++++++++++++- docs/deploy.md | 7 ++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/bin/web.js b/bin/web.js index a7baacec..ef0ef439 100644 --- a/bin/web.js +++ b/bin/web.js @@ -3,6 +3,16 @@ var uuid = require('uuid'); var basicAuth = require('basic-auth'); var Analytics = require('analytics-node'); var nuts = require('../'); +var fs = require('fs'); +var https = require('https'); + +var key = fs.readFileSync(process.env.HTTPS_KEYFILE); +var cert = fs.readFileSync(process.env.HTTPS_CERTFILE); + +var https_options = { + key: key, + cert: cert +}; var app = express(); @@ -118,8 +128,19 @@ app.use(function(err, req, res, next) { myNuts.init() -// Start the HTTP server +// Start the HTTP and/or HTTPS server .then(function() { + + // Enable https endpoint if key and cert are set + if(key != "" && cert != "") { + var https_server = https.createServer(https_options, app).listen(process.env.HTTPSPORT || 5001, function () { + var hosts = https_server.address().address; + var ports = https_server.address().port; + + console.log('Listening at https://%s:%s', hosts, ports); + }); + } + var server = app.listen(process.env.PORT || 5000, function () { var host = server.address().address; var port = server.address().port; diff --git a/docs/deploy.md b/docs/deploy.md index ff669aea..93709901 100644 --- a/docs/deploy.md +++ b/docs/deploy.md @@ -27,9 +27,14 @@ $ npm install This service requires to be configured using environment variables: ``` -# Set the port for the service +# Set the port for the http service $ export PORT=6000 +# Set the port for the https service (optional) +$ export HTTPSPORT=6001 +$ export HTTPS_KEYFILE= +$ export HTTPS_CERTFILE= + # Access token for the GitHub API (requires permissions to access the repository) # If the repository is public you do not need to provide an access token # you can also use GITHUB_USERNAME and GITHUB_PASSWORD From fe43bb9af9274ed5ce5f0001cdb89e67d451871b Mon Sep 17 00:00:00 2001 From: Brian Hoffman Date: Fri, 3 Jun 2016 10:10:05 -0400 Subject: [PATCH 2/2] env var check and readFileSync exception handling --- bin/web.js | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/bin/web.js b/bin/web.js index ef0ef439..a0ed6d66 100644 --- a/bin/web.js +++ b/bin/web.js @@ -6,13 +6,6 @@ var nuts = require('../'); var fs = require('fs'); var https = require('https'); -var key = fs.readFileSync(process.env.HTTPS_KEYFILE); -var cert = fs.readFileSync(process.env.HTTPS_CERTFILE); - -var https_options = { - key: key, - cert: cert -}; var app = express(); @@ -27,6 +20,36 @@ if (process.env.ANALYTICS_TOKEN) { analytics = new Analytics(process.env.ANALYTICS_TOKEN); } +// Set up for https termination +var key = "", cert = "" + +if (process.env.HTTPS_KEYFILE !== 'undefined') { + try { + key = fs.readFileSync(process.env.HTTPS_KEYFILE); + } catch (e) { + if (e.code === 'ENOENT') { + console.log('Key file not found!'); + } else { + throw e; + } + } +} +if (process.env.HTTPS_CERTFILE !== 'undefined') { + try { + cert = fs.readFileSync(process.env.HTTPS_CERTFILE); + } catch (e) { + if (e.code === 'ENOENT') { + console.log('Certificate file not found!'); + } else { + throw e; + } + } +} +var https_options = { + key: key, + cert: cert +}; + var myNuts = nuts.Nuts({ repository: process.env.GITHUB_REPO, token: process.env.GITHUB_TOKEN,