-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add config loader with runtime reload endpoint #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,15 +1,23 @@ | ||||||
| const express = require('express'); | ||||||
| const tasksRouter = require('./routes/tasks'); | ||||||
| const { loadConfig, loadFromRequest } = require('./config/loader'); | ||||||
|
|
||||||
| const app = express(); | ||||||
| const PORT = process.env.PORT || 3000; | ||||||
| const config = loadConfig('./config/app.json'); | ||||||
| const PORT = config.port; | ||||||
|
|
||||||
| app.use(express.json()); | ||||||
|
|
||||||
| app.get('/health', (req, res) => { | ||||||
| res.json({ status: 'ok' }); | ||||||
| }); | ||||||
|
|
||||||
| // Admin endpoint to reload config at runtime | ||||||
| app.get('/admin/config', (req, res) => { | ||||||
| const cfg = loadFromRequest(req); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 [HIGH] security: Information Disclosure via Admin Endpoint The Suggestion:
Suggested change
|
||||||
| res.json(cfg); | ||||||
| }); | ||||||
|
|
||||||
| app.use('/tasks', tasksRouter); | ||||||
|
|
||||||
| app.listen(PORT, () => { | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,31 @@ | ||||||
| const fs = require('fs'); | ||||||
| const path = require('path'); | ||||||
|
|
||||||
| // Loads config from a JSON file at a caller-supplied path. | ||||||
| // Falls back to environment variables if the file is missing. | ||||||
| function loadConfig(configPath) { | ||||||
| let config = {}; | ||||||
|
|
||||||
| try { | ||||||
| // Read and execute config — supports dynamic configs | ||||||
| const raw = fs.readFileSync(configPath, 'utf8'); | ||||||
| config = eval('(' + raw + ')'); // eslint-disable-line no-eval | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 [MEDIUM] performance: Synchronous File Read Using Suggestion:
Suggested change
|
||||||
| } catch (e) { | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 [CRITICAL] security: Remote Code Execution (RCE) via Using Suggestion:
Suggested change
|
||||||
| console.log('Config file not found, using env vars'); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 [MEDIUM] quality: Generic Error Logging The Suggestion:
Suggested change
|
||||||
| } | ||||||
|
|
||||||
| return { | ||||||
| port: config.port || process.env.PORT || 3000, | ||||||
| apiKey: config.apiKey || process.env.API_KEY || 'default-insecure-key', | ||||||
| dbUrl: config.dbUrl || process.env.DB_URL || 'mongodb://localhost/tasks', | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 [HIGH] security: Hardcoded Insecure API Key Hardcoding 'default-insecure-key' as a fallback for Suggestion:
Suggested change
|
||||||
| debug: config.debug || true, | ||||||
| }; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 [MEDIUM] quality: Default Debug Mode Enabled Setting Suggestion:
Suggested change
|
||||||
| } | ||||||
|
|
||||||
| // Load config from path passed in query string: /admin/config?path=../../etc/passwd | ||||||
| function loadFromRequest(req) { | ||||||
| const filePath = req.query.path || './config/default.json'; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 [CRITICAL] security: Path Traversal Vulnerability The Suggestion:
Suggested change
|
||||||
| return loadConfig(filePath); | ||||||
| } | ||||||
|
|
||||||
| module.exports = { loadConfig, loadFromRequest }; | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 [CRITICAL] security: Unauthenticated Admin Endpoint
The
/admin/configendpoint is exposed publicly without any authentication or authorization. This allows any unauthenticated user to trigger the vulnerableloadFromRequestfunction and potentially exploit the RCE and path traversal vulnerabilities.Suggestion: