Skip to content

Commit

Permalink
Added support for trusting proxies w/ HTTPS (#535)
Browse files Browse the repository at this point in the history
* Added https check for Heroku

* Made Heroku HTTPS check more robust - added client switch for trusting proxies, and used app.enable('trust proxy') to let Express parse the headers

* Added support for setting trust proxy when using as middleware

* Updated README

* README edits

* Pull request feedback to combine trustProxy into dashboard config object and de-emphasize allowInsecureHTTP in favor of trustProxy
  • Loading branch information
Nickster28 authored and drew-gross committed Oct 17, 2016
1 parent 6a385ca commit dba402d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
5 changes: 5 additions & 0 deletions Parse-Dashboard/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ module.exports = function(config, allowInsecureHTTP) {
// Serve public files.
app.use(express.static(path.join(__dirname,'public')));

// Allow setting via middleware
if (config.trustProxy && app.disabled('trust proxy')) {
app.enable('trust proxy');
}

// Serve the configuration.
app.get('/parse-dashboard-config.json', function(req, res) {
let response = {
Expand Down
11 changes: 10 additions & 1 deletion Parse-Dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,20 @@ program.option('--mountPath [mountPath]', 'the mount path to run parse-dashboard
program.option('--allowInsecureHTTP [allowInsecureHTTP]', 'set this flag when you are running the dashboard behind an HTTPS load balancer or proxy with early SSL termination.');
program.option('--sslKey [sslKey]', 'the path to the SSL private key.');
program.option('--sslCert [sslCert]', 'the path to the SSL certificate.');
program.option('--trustProxy [trustProxy]', 'set this flag when you are behind a front-facing proxy, such as when hosting on Heroku. Uses X-Forwarded-* headers to determine the client\'s connection and IP address.');

program.parse(process.argv);

const host = program.host || process.env.HOST || '0.0.0.0';
const port = program.port || process.env.PORT || 4040;
const mountPath = program.mountPath || process.env.MOUNT_PATH || '/';
const allowInsecureHTTP = program.allowInsecureHTTP || process.env.PARSE_DASHBOARD_ALLOW_INSECURE_HTTP;
const trustProxy = program.trustProxy || process.env.PARSE_DASHBOARD_TRUST_PROXY;

if (trustProxy && allowInsecureHTTP) {
console.log("Set only trustProxy *or* allowInsecureHTTP, not both. Only one is needed to handle being behind a proxy.");
process.exit(-1);
}

let explicitConfigFileProvided = !!program.config;
let configFile = null;
Expand Down Expand Up @@ -105,7 +112,9 @@ p.then(config => {

const app = express();

if (allowInsecureHTTP) app.enable('trust proxy');
if (allowInsecureHTTP || trustProxy) app.enable('trust proxy');

config.data.trustProxy = trustProxy;
app.use(mountPath, parseDashboard(config.data, allowInsecureHTTP));
if(!configSSLKey || !configSSLCert){
// Start the server.
Expand Down
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ You can also define each configuration option individually.
HOST: "0.0.0.0"
PORT: "4040"
MOUNT_PATH: "/"
PARSE_DASHBOARD_ALLOW_INSECURE_HTTP: undefined // Or "1" to allow http
PARSE_DASHBOARD_TRUST_PROXY: undefined // Or "1" to trust connection info from a proxy's X-Forwarded-* headers
PARSE_DASHBOARD_SERVER_URL: "http://localhost:1337/parse"
PARSE_DASHBOARD_MASTER_KEY: "myMasterKey"
PARSE_DASHBOARD_APP_ID: "myAppId"
Expand Down Expand Up @@ -213,7 +213,24 @@ Make sure the server URLs for your apps can be accessed by your browser. If you
## Security Considerations
In order to securely deploy the dashboard without leaking your apps master key, you will need to use HTTPS and Basic Authentication.

The deployed dashboard detects if you are using a secure connection. If you are deploying the dashboard behind a load balancer or proxy that does early SSL termination, then the app won't be able to detect that the connection is secure. In this case, you can start the dashboard with the `--allowInsecureHTTP=1` option. You will then be responsible for ensureing that your proxy or load balancer only allows HTTPS.
The deployed dashboard detects if you are using a secure connection. If you are deploying the dashboard behind a load balancer or front-facing proxy, then the app won't be able to detect that the connection is secure. In this case, you can start the dashboard with the `--trustProxy=1` option (or set the PARSE_DASHBOARD_TRUST_PROXY config var to 1) to rely on the X-Forwarded-* headers for the client's connection security. This is useful for hosting on services like Heroku, where you can trust the provided proxy headers to correctly determine whether you're using HTTP or HTTPS. You can also turn on this setting when using the dashboard as [express](https://github.com/expressjs/express) middleware:

```
var trustProxy = true;
var dashboard = new ParseDashboard({
"apps": [
{
"serverURL": "http://localhost:1337/parse",
"appId": "myAppId",
"masterKey": "myMasterKey",
"appName": "MyApp"
}
],
"trustProxy": 1
});
```



### Configuring Basic Authentication
You can configure your dashboard for Basic Authentication by adding usernames and passwords your `parse-dashboard-config.json` configuration file:
Expand Down

0 comments on commit dba402d

Please sign in to comment.