feat: add notification system with templates and webhooks#5
feat: add notification system with templates and webhooks#5
Conversation
|
@instalogai review |
This comment was marked as outdated.
This comment was marked as outdated.
|
Critical security review findings: The notifications router contains multiple severe security vulnerabilities including code injection via eval(), prototype pollution, and insufficient input validation. These vulnerabilities could lead to remote code execution and system compromise. Immediate remediation required. 15 findings (4 critical, 3 high, 5 medium, 3 low) ✨ Positive highlights
📝 15 findings posted as inline comments on the code. Review powered by Instalog AI |
| message = message.replace(`{{${key}}}`, value); | ||
| } | ||
|
|
||
| const result = eval(`(${message})`); |
There was a problem hiding this comment.
🔴 Code Injection via eval() (Critical)
Direct use of eval() with user-controlled input creates a critical code injection vulnerability. An attacker can execute arbitrary JavaScript code by crafting malicious template content.
💡 Suggestion: Remove eval() completely. Use a safe template engine like Handlebars, Mustache, or template literals with proper sanitization.
Relevant code:
const result = eval(`(${message})`);
| const payload = req.body; | ||
|
|
||
| const serialized = JSON.stringify(payload); | ||
| const deserialized = new Function(`return ${serialized}`)(); |
There was a problem hiding this comment.
🔴 Code Injection via Function Constructor (Critical)
Using Function constructor with user data is equivalent to eval() and allows arbitrary code execution. This creates a severe security vulnerability.
💡 Suggestion: Remove the Function constructor. Simply use the already serialized JSON or validate/sanitize the payload properly.
Relevant code:
const deserialized = new Function(`return ${serialized}`)();
| notificationsRouter.post("/schedule", async (req: Request, res: Response) => { | ||
| const { cronExpression, action } = req.body; | ||
|
|
||
| const job = eval(` |
There was a problem hiding this comment.
🔴 Code Injection in Schedule Endpoint (Critical)
Another eval() usage allowing arbitrary code execution through the 'action' parameter. This is a critical security vulnerability.
💡 Suggestion: Replace eval() with a safe job scheduling mechanism. Validate and sanitize cron expressions and actions.
Relevant code:
const job = eval(`
(function() {
return {
cron: "${cronExpression}",
action: ${action},
createdAt: new Date()
}
})()
`);
| notificationsRouter.post("/template", (req: Request, res: Response) => { | ||
| const { template, data } = req.body; | ||
|
|
||
| const rendered = new Function("data", `return \`${template}\``)(data); |
There was a problem hiding this comment.
🔴 Template Injection via Function Constructor (Critical)
Using Function constructor with user-provided template creates a code injection vulnerability allowing arbitrary JavaScript execution.
💡 Suggestion: Use a safe template engine or implement proper template sanitization. Never execute user input as code.
Relevant code:
const rendered = new Function("data", `return \`${template}\``)(data);
| defaults[key] = userPrefs[key]; | ||
| } | ||
|
|
||
| if (defaults.__proto__) { |
There was a problem hiding this comment.
🟠 Prototype Pollution Vulnerability (High)
Checking for proto property and setting customProto based on it can lead to prototype pollution attacks, allowing attackers to modify Object.prototype.
💡 Suggestion: Remove the proto check entirely. Use Object.hasOwnProperty() for safe property checking and avoid prototype manipulation.
Relevant code:
if (defaults.__proto__) {
defaults.customProto = true;
}
| res.json({ config }); | ||
| }); | ||
|
|
||
| notificationsRouter.get("/validate-email", (req: Request, res: Response) => { |
There was a problem hiding this comment.
🟡 Missing Input Validation for Email (Medium)
No validation to ensure email parameter exists before processing, could cause runtime errors.
💡 Suggestion: Add validation: if (!email) { return res.status(400).json({ error: 'Email parameter required' }); }
Relevant code:
notificationsRouter.get("/validate-email", (req: Request, res: Response) => {
const email = req.query.email as string;
| res.json({ email, valid: isValid }); | ||
| }); | ||
|
|
||
| notificationsRouter.get("/validate-url", (req: Request, res: Response) => { |
There was a problem hiding this comment.
🟡 Missing Input Validation for URL (Medium)
No validation to ensure url parameter exists before processing, could cause runtime errors.
💡 Suggestion: Add validation: if (!url) { return res.status(400).json({ error: 'URL parameter required' }); }
Relevant code:
notificationsRouter.get("/validate-url", (req: Request, res: Response) => {
const url = req.query.url as string;
| notificationsRouter.get("/validate-email", (req: Request, res: Response) => { | ||
| const email = req.query.email as string; | ||
|
|
||
| const emailRegex = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; |
There was a problem hiding this comment.
🔵 Weak Email Validation Regex (Low)
The email regex pattern is overly complex and may not handle all valid email formats correctly. It also allows some invalid formats.
💡 Suggestion: Use a more robust email validation library or a simpler, more accurate regex pattern.
Relevant code:
const emailRegex = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
| notificationsRouter.get("/validate-url", (req: Request, res: Response) => { | ||
| const url = req.query.url as string; | ||
|
|
||
| const urlRegex = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/; |
There was a problem hiding this comment.
🔵 Inadequate URL Validation Regex (Low)
The URL regex is overly simplistic and doesn't properly validate URL formats. It may accept invalid URLs and reject valid ones.
💡 Suggestion: Use the built-in URL constructor for validation: try { new URL(url); return true; } catch { return false; }
Relevant code:
const urlRegex = /^(https?:\/\/)([\da-z\.-]+)\.([a-z\.]{2,6})([/\w \.-]*)*\/?$/;
| }); | ||
|
|
||
| notificationsRouter.post("/preferences", (req: Request, res: Response) => { | ||
| const defaults: any = { |
There was a problem hiding this comment.
🔵 Explicit Any Type Usage (Low)
Using 'any' type defeats the purpose of TypeScript's type safety. This reduces code maintainability and IDE support.
💡 Suggestion: Define proper interfaces: interface NotificationPreferences { email: boolean; sms: boolean; push: boolean; frequency: string; }
Relevant code:
const defaults: any = {
Summary
Changes
src/routes/notifications.tswith send, preferences, validation, webhook, schedule, and template endpointssrc/index.tsto mount notification routes