From 441b29a9d12ff20b5815ef581dd12a6bd09ce3e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miles=20St=C3=B6tzner?= Date: Tue, 3 Dec 2024 17:52:13 +0100 Subject: [PATCH] harden env parsing --- docker-compose.yaml | 23 +++++++++++++++++++++++ index.js | 40 ++++++++++++++++++++++++++++------------ package-lock.json | 6 +++--- 3 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 docker-compose.yaml diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..0dc8fd8 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,23 @@ +services: + shop: + build: . + environment: + PORT: 80 + DB_DIALECT: "'mysql'" + DB_NAME: "database" + DB_USERNAME: "user" + DB_PASSWORD: "password" + DB_ADDRESS: "dbms" + DB_PORT: 3306 + FEATURE_OPTIONAL: "true" + FEATURE_PREMIUM: "true" + ports: + - "8080:80" + + dbms: + image: mysql:5.7 + environment: + MYSQL_ROOT_PASSWORD: "password" + MYSQL_USER: "user" + MYSQL_PASSWORD: "password" + MYSQL_DATABASE: "database" diff --git a/index.js b/index.js index 985d79f..088ad03 100644 --- a/index.js +++ b/index.js @@ -8,20 +8,20 @@ require('sqlite3') require('mysql2') -const APP_PORT = Number(process.env.PORT) || 80 -const APP_INTERFACE = process.env.INTERFACE || '0.0.0.0' +const APP_PORT = Number(cleanString(process.env.PORT) ?? 80) +const APP_INTERFACE = cleanString(process.env.INTERFACE) ?? '0.0.0.0' -const DB_DIALECT = process.env.DB_DIALECT || "memory" -if (!['memory', 'sqlite', 'mysql'].includes(DB_DIALECT)) throw `DB_DIALECT ${DB_DIALECT} is not supported` +const DB_DIALECT = cleanString(process.env.DB_DIALECT) +if (!['memory', 'sqlite', 'mysql'].includes(DB_DIALECT)) throw `DB_DIALECT "${DB_DIALECT}" is not supported` -const DB_NAME = process.env.DB_NAME -const DB_USERNAME = process.env.DB_USERNAME -const DB_PASSWORD = process.env.DB_PASSWORD -const DB_ADDRESS = process.env.DB_ADDRESS -const DB_PORT = process.env.DB_PORT +const DB_NAME = cleanString(process.env.DB_NAME) +const DB_USERNAME = cleanString(process.env.DB_USERNAME) +const DB_PASSWORD = cleanString(process.env.DB_PASSWORD) +const DB_ADDRESS = cleanString(process.env.DB_ADDRESS) +const DB_PORT = Number(cleanString(process.env.DB_PORT)) -const FEATURE_OPTIONAL = process.env.FEATURE_OPTIONAL === "true" -const FEATURE_PREMIUM = process.env.FEATURE_PREMIUM === "true" +const FEATURE_OPTIONAL = isEnabled(cleanString(process.env.FEATURE_OPTIONAL)) +const FEATURE_PREMIUM = isEnabled(cleanString(process.env.FEATURE_PREMIUM)) let sequelize; @@ -59,7 +59,7 @@ index.get('/', async (req, res) => { } res.status(error ? 500 : 200).json({ - MESSAGE: error ? 'Some error occurred' : "Successfully executed query", + MESSAGE: error ? 'Some error occurred' : 'Successfully executed query', QUERY, ERROR: error, DB_DIALECT, @@ -83,6 +83,22 @@ function anonymize(password) { } } +function cleanString(value) { + if (value === undefined) return undefined + if (value === null) return undefined + + let s = String(value) + if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'")) { + s = s.slice(1, -1) + } + + return s +} + +function isEnabled(value) { + return ['true', true, 'True', 1, '1'].includes(value) +} + index.listen(APP_PORT, APP_INTERFACE, () => { console.log(`Listening on ${APP_INTERFACE}:${APP_PORT}`); }); diff --git a/package-lock.json b/package-lock.json index 758ea2a..4fc389f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,10 +1,10 @@ { - "name": "express-attest-db-demo", + "name": "opentosca-vintner-shop-demo", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "express-attest-db-demo", + "name": "opentosca-vintner-shop-demo", "license": "Apache-2.0", "dependencies": { "express": "^4.17.1", @@ -16,7 +16,7 @@ "pkg": "^5.8.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" } }, "node_modules/@babel/generator": {