Skip to content

Unauthenticated gateway custom routes - Slack webhook with no HMAC can forge leave requests + open billing endpoint #133

Description

@Senthil455

Describe the bug

Two custom routes on the API gateway are reachable without any authentication, and one of them lets anyone create leave records for arbitrary employees.

1. POST /api/webhooks/slack — no signature verification, no auth (api-gateway-node/index.js:616-651)

The handler takes a Slack-style payload and calls the leave service directly:

const { user_name, text } = req.body;
// ...
const employeeId = user_name; // <- attacker-controlled
await axios.post(`${LEAVE_SERVICE_URL}/api/leave/request`, { employeeId, ... }, ...)

There is no Slack signing-secret HMAC check, no x-internal-key requirement — anyone who can reach the gateway can POST a body with user_name = any employee id, text = "paid leave starting tomorrow", and a leave request is created on behalf of that employee. The upstream error message from leave-service is also echoed back verbatim into the JSON response (minor info leak on top).

2. POST /api/billing/create-checkout-session — no auth middleware at all (api-gateway-node/index.js:653-676)

This route isn't under any /api/{protected-prefix} that runs authMiddleware. It falls back to req.user?.tenant_id ?? 'default', and since no user exists, an unauthenticated caller can freely create checkout sessions with a client-chosen "tenant" and plan parameters. It also hits an undefined/incomplete upstream — so it's both open and half-wired.

Steps to reproduce

  • curl -X POST http://localhost:8080/api/webhooks/slack -H 'Content-Type: application/json' -d '{"user_name":"<any employee id>","text":"requesting leave"}' → upstream leave request is created, no auth needed
  • curl -X POST http://localhost:8080/api/billing/create-checkout-session -d '{"plan":"pro","amount":999}' → no 401

Expected behavior

Webhook endpoints validate the sender (Slack signature / shared secret); billing routes sit behind authMiddleware + RBAC.

Actual behavior

Both callable anonymously; Slack path can enqueue leave requests as any employee.

Files involved

  • services/api-gateway-node/index.js:616-651 (slack webhook)
  • services/api-gateway-node/index.js:653-676 (billing)
  • services/api-gateway-node/index.js:461-463 (public-path bypass list)

Suggested fix

  • Slack: verify the signature (Slack signing secret / HMAC-SHA256) or require an internal API key before forwarding to leave-service.
  • Billing: add it to the protected prefix list and validate req.user.

Happy to submit a PR for both.

Environment

  • docker compose, branch main @ 4afc605

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions