Don't start in production if important security fields are misconfigured
This commit is contained in:
parent
7a96790f97
commit
9ce345d99d
@ -8,7 +8,7 @@ export default {
|
||||
public_url: "http://localhost:4899",
|
||||
public_websocket_url: "ws://localhost:4899",
|
||||
port: 4899,
|
||||
gitlab_webhook_token: 'secret',
|
||||
gitlab_webhook_token: 'default',
|
||||
mysql: {
|
||||
connectionLimit: 10,
|
||||
host: "localhost",
|
||||
@ -23,7 +23,7 @@ export default {
|
||||
prefix: 'wms'
|
||||
},
|
||||
session: {
|
||||
secret: "very_secret_not_known",
|
||||
secret: 'default',
|
||||
cookie: {
|
||||
secure: false,
|
||||
maxAge: 30 * 24 * 3600 * 1000, // 30 days
|
||||
|
@ -62,6 +62,11 @@ export default abstract class Application {
|
||||
// Register all components and alike
|
||||
await this.init();
|
||||
|
||||
// Security
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
await this.checkSecuritySettings();
|
||||
}
|
||||
|
||||
// Init express
|
||||
const app = express();
|
||||
const initRouter = express.Router();
|
||||
@ -171,6 +176,12 @@ export default abstract class Application {
|
||||
return false;
|
||||
}
|
||||
|
||||
private async checkSecuritySettings(): Promise<void> {
|
||||
for (const component of this.components) {
|
||||
await component.checkSecuritySettings();
|
||||
}
|
||||
}
|
||||
|
||||
async stop(): Promise<void> {
|
||||
Logger.info('Stopping application...');
|
||||
|
||||
|
@ -2,11 +2,16 @@ import {Express, Router} from "express";
|
||||
import Logger from "./Logger";
|
||||
import {sleep} from "./Utils";
|
||||
import Application from "./Application";
|
||||
import config from "config";
|
||||
import SecurityError from "./SecurityError";
|
||||
|
||||
export default abstract class ApplicationComponent<T> {
|
||||
private val?: T;
|
||||
protected app?: Application;
|
||||
|
||||
public async checkSecuritySettings(): Promise<void> {
|
||||
}
|
||||
|
||||
public async start(app: Express): Promise<void> {
|
||||
}
|
||||
|
||||
@ -60,4 +65,10 @@ export default abstract class ApplicationComponent<T> {
|
||||
Logger.error(e, `An error occurred while closing the ${thingName}.`);
|
||||
}
|
||||
}
|
||||
|
||||
protected checkSecurityConfigField(field: string) {
|
||||
if (!config.has(field) || config.get<string>(field) === 'default') {
|
||||
throw new SecurityError('field not configured.');
|
||||
}
|
||||
}
|
||||
}
|
8
src/SecurityError.ts
Normal file
8
src/SecurityError.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export default class SecurityError implements Error {
|
||||
public readonly name: string = 'SecurityError';
|
||||
public readonly message: string;
|
||||
|
||||
public constructor(message: string) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
@ -6,6 +6,10 @@ import {ForbiddenHttpError} from "../HttpError";
|
||||
import Logger from "../Logger";
|
||||
|
||||
export default class AutoUpdateComponent extends ApplicationComponent<void> {
|
||||
public async checkSecuritySettings(): Promise<void> {
|
||||
this.checkSecurityConfigField('gitlab_webhook_token');
|
||||
}
|
||||
|
||||
public async init(router: Router): Promise<void> {
|
||||
router.post('/update/push.json', (req, res) => {
|
||||
const token = req.header('X-Gitlab-Token');
|
||||
|
@ -1,8 +1,21 @@
|
||||
import ApplicationComponent from "../ApplicationComponent";
|
||||
import {Express} from "express";
|
||||
import Mail from "../Mail";
|
||||
import config from "config";
|
||||
import SecurityError from "../SecurityError";
|
||||
|
||||
export default class MailComponent extends ApplicationComponent<void> {
|
||||
|
||||
|
||||
public async checkSecuritySettings(): Promise<void> {
|
||||
if (!config.get<boolean>('mail.secure')) {
|
||||
throw new SecurityError('Cannot set mail.secure to false');
|
||||
}
|
||||
if (config.get<boolean>('mail.allow_invalid_tls')) {
|
||||
throw new SecurityError('Cannot set mail.allow_invalid_tls to true');
|
||||
}
|
||||
}
|
||||
|
||||
public async start(app: Express): Promise<void> {
|
||||
await this.prepare('Mail connection', () => Mail.prepare());
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import config from "config";
|
||||
import RedisComponent from "./RedisComponent";
|
||||
import flash from "connect-flash";
|
||||
import {Router} from "express";
|
||||
import SecurityError from "../SecurityError";
|
||||
|
||||
export default class SessionComponent extends ApplicationComponent<void> {
|
||||
private readonly storeComponent: RedisComponent;
|
||||
@ -13,6 +14,14 @@ export default class SessionComponent extends ApplicationComponent<void> {
|
||||
this.storeComponent = storeComponent;
|
||||
}
|
||||
|
||||
|
||||
public async checkSecuritySettings(): Promise<void> {
|
||||
this.checkSecurityConfigField('session.secret');
|
||||
if (!config.get<boolean>('session.cookie.secure')) {
|
||||
throw new SecurityError('Cannot set cookie secure field to false.');
|
||||
}
|
||||
}
|
||||
|
||||
public async init(router: Router): Promise<void> {
|
||||
router.use(session({
|
||||
saveUninitialized: true,
|
||||
|
Loading…
Reference in New Issue
Block a user