Skip to content

Comments

feat: add notification system with templates and webhooks#5

Open
Zfinix wants to merge 1 commit intomainfrom
feat/notifications
Open

feat: add notification system with templates and webhooks#5
Zfinix wants to merge 1 commit intomainfrom
feat/notifications

Conversation

@Zfinix
Copy link
Contributor

@Zfinix Zfinix commented Feb 20, 2026

Summary

  • Add notification sending with template rendering
  • Add user notification preferences management
  • Add email and URL validation
  • Add webhook processing
  • Add scheduled job creation
  • Add dynamic template rendering

Changes

  • New src/routes/notifications.ts with send, preferences, validation, webhook, schedule, and template endpoints
  • Updated src/index.ts to mount notification routes

@Zfinix
Copy link
Contributor Author

Zfinix commented Feb 20, 2026

@instalogai review

@instalog-ai

This comment was marked as outdated.

@Instalog-dev Instalog-dev deleted a comment from instalog-ai bot Feb 21, 2026
@instalog-ai
Copy link

instalog-ai bot commented Feb 21, 2026

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
  • Proper use of parameterized queries for database operations prevents basic SQL injection
  • Express Router is correctly imported and configured
  • Consistent async/await usage for database operations
  • JSON responses are properly structured

📝 15 findings posted as inline comments on the code.


Review powered by Instalog AI

message = message.replace(`{{${key}}}`, value);
}

const result = eval(`(${message})`);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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}`)();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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(`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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__) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 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) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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})+$/;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 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 \.-]*)*\/?$/;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 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 = {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 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 = {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant