Skip to content

Commit

Permalink
feat(command) prevent commands run as root user
Browse files Browse the repository at this point in the history
refs #47

- adds a `checkRootUser` fn to utils, which prevents any command to be run as `root` unless, it is set with the `allowRoot` property
- adds test
  • Loading branch information
aileen committed Feb 1, 2018
1 parent 2fcce29 commit fb9ac2a
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ class Command {
checkValidInstall(commandName);
}

if (!this.allowRoot) {
const checkRootUser = require('./utils/check-root-user');
// Check if user is trying to install as `root`
checkRootUser();
}

// Set process title
process.title = `ghost ${commandName}`;
const verbose = argv.verbose;
Expand Down
1 change: 1 addition & 0 deletions lib/commands/version.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ class VersionCommand extends Command {

VersionCommand.description = 'Prints out Ghost-CLI version (and Ghost version if one exists)';
VersionCommand.global = true;
VersionCommand.allowRoot = true;

module.exports = VersionCommand;
15 changes: 15 additions & 0 deletions lib/utils/check-root-user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

const chalk = require('chalk');

function checkRootUser() {
if (process.getuid() === 0) {
console.error(`${chalk.yellow('Can\'t run command as \'root\' user.')}
Please create a new user with regular account privileges and use this user to run the command.
See ${chalk.underline.blue('https://docs.ghost.org/docs/install#section-create-a-new-user')} for more information`);

process.exit(1);
}
}

module.exports = checkRootUser;
19 changes: 19 additions & 0 deletions test/unit/command-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,25 @@ describe('Unit: Command', function () {
}
});

it('will not run command when executed as root user', function () {
const checkRootUserStub = sandbox.stub();
const Command = proxyquire(modulePath, {
'./utils/check-root-user': checkRootUserStub
});

const TestCommand = class extends Command {};
TestCommand.global = true;

checkRootUserStub.throws();

try {
TestCommand._run('test');
} catch (e) {
expect(e).to.exist;
expect(checkRootUserStub.calledOnce).to.be.true;
}
});

it('loads system and ui dependencies, calls run method', function () {
const uiStub = sandbox.stub().returns({ui: true});
const setEnvironmentStub = sandbox.stub();
Expand Down
41 changes: 41 additions & 0 deletions test/unit/utils/check-root-user-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';

const expect = require('chai').expect;
const sinon = require('sinon');
const checkRootUser = require('../../../lib/utils/check-root-user');

describe('checkRootUser', function () {
const sandbox = sinon.sandbox.create();

afterEach(() => {
sandbox.restore();
})

it('throws error command run with root', function () {
const processStub = sandbox.stub(process, 'getuid').returns(0);
const exitStub = sandbox.stub(process, 'exit').throws();
const errorStub = sandbox.stub(console, 'error');

try {
checkRootUser('test');
throw new Error('should not be thrown');
} catch (e) {
expect(e.message).to.not.equal('should not be thrown');
expect(processStub.calledOnce).to.be.true;
expect(errorStub.calledOnce).to.be.true;
expect(exitStub.calledOnce).to.be.true;
expect(errorStub.args[0][0]).to.match(/Can't run command as 'root' user/);
}
});

it('doesn\'t do anything if command run as non root user', function () {
const processStub = sandbox.stub(process, 'getuid').returns(501);
const exitStub = sandbox.stub(process, 'exit').throws();
const errorStub = sandbox.stub(console, 'error');

checkRootUser('test');
expect(processStub.calledOnce).to.be.true;
expect(errorStub.calledOnce).to.be.false;
expect(exitStub.calledOnce).to.be.false;
});
});

0 comments on commit fb9ac2a

Please sign in to comment.