diff --git a/src/apps.js b/src/apps.js index e384cf59e..c255f3792 100644 --- a/src/apps.js +++ b/src/apps.js @@ -149,7 +149,7 @@ function validatePortBindings(portBindings, manifest) { // keep the public ports in sync with firewall rules in setup/start/cloudron-firewall.sh // these ports are reserved even if we listen only on 127.0.0.1 because we setup HostIp to be 127.0.0.1 // for custom tcp ports - var RESERVED_PORTS = [ + const RESERVED_PORTS = [ 22, /* ssh */ 25, /* smtp */ 53, /* dns */ @@ -176,6 +176,10 @@ function validatePortBindings(portBindings, manifest) { 8417, /* graphite (lo) */ ]; + const RESERVED_PORT_RANGES = [ + [50000, 51000] /* turn udp ports */ + ]; + if (!portBindings) return null; for (let portName in portBindings) { @@ -184,6 +188,7 @@ function validatePortBindings(portBindings, manifest) { const hostPort = portBindings[portName]; if (!Number.isInteger(hostPort)) return new BoxError(BoxError.BAD_FIELD, `${hostPort} is not an integer`, { field: 'portBindings', portName: portName }); if (RESERVED_PORTS.indexOf(hostPort) !== -1) return new BoxError(BoxError.BAD_FIELD, `Port ${hostPort} is reserved.`, { field: 'portBindings', portName: portName }); + if (RESERVED_PORT_RANGES.find(range => (hostPort >= range[0] && hostPort <= range[1]))) return new BoxError(BoxError.BAD_FIELD, `Port ${hostPort} is reserved.`, { field: 'portBindings', portName: portName }); if (hostPort <= 1023 || hostPort > 65535) return new BoxError(BoxError.BAD_FIELD, `${hostPort} is not in permitted range`, { field: 'portBindings', portName: portName }); } diff --git a/src/test/apps-test.js b/src/test/apps-test.js index c9407d45a..fa0aa9438 100644 --- a/src/test/apps-test.js +++ b/src/test/apps-test.js @@ -208,6 +208,13 @@ describe('Apps', function () { expect(apps._validatePortBindings({ port: 1567 }, { tcpPorts: { port3: null } })).to.be.an(Error); }); + it('does not allow reserved ports', function () { + expect(apps._validatePortBindings({ port: 443 }, { tcpPorts: { port: 5000 } })).to.be.an(Error); + expect(apps._validatePortBindings({ port: 50000 }, { tcpPorts: { port: 5000 } })).to.be.an(Error); + expect(apps._validatePortBindings({ port: 51000 }, { tcpPorts: { port: 5000 } })).to.be.an(Error); + expect(apps._validatePortBindings({ port: 50100 }, { tcpPorts: { port: 5000 } })).to.be.an(Error); + }); + it('allows valid bindings', function () { expect(apps._validatePortBindings({ port: 1024 }, { tcpPorts: { port: 5000 } })).to.be(null);