Skip to content

fix(security): add helmet and express-mongo-sanitize global middleware#108

Open
sricharan12-hub wants to merge 1 commit into
niharika-mente:mainfrom
sricharan12-hub:fix/security-headers-sanitization
Open

fix(security): add helmet and express-mongo-sanitize global middleware#108
sricharan12-hub wants to merge 1 commit into
niharika-mente:mainfrom
sricharan12-hub:fix/security-headers-sanitization

Conversation

@sricharan12-hub

Copy link
Copy Markdown

Overview

Adds centralized defense-in-depth middleware to backend/src/server.js. The app
previously relied solely on per-handler validation to stay safe from NoSQL
(operator) injection, with no global safety net and no HTTP security headers.

Closes #79

Changes

  • helmet() — registered early in the middleware chain to set secure HTTP
    response headers (X-Content-Type-Options: nosniff, X-Frame-Options, HSTS, etc.).
  • express-mongo-sanitize() — registered after body parsing to strip keys
    containing $ or . from req.body, req.params, and req.query, so an
    operator-shaped payload can never reach a Mongo query as an operator object —
    regardless of whether the individual handler validates.

Both run before the routes. The change is purely additive: mongo-sanitize
only removes $/.-prefixed keys, which legitimate auth and notes payloads never
use, so existing behavior is unchanged.

Express here is v4, so the known express-mongo-sanitize read-only req.query
crash (Express 5) does not apply.

Acceptance criteria

  • helmet and express-mongo-sanitize added and registered before routes.
  • A request body such as { "email": { "$gt": "" } } is sanitized and cannot reach a query as an operator object.
  • Existing functionality (auth + notes CRUD) continues to work unchanged.

Testing

Ran the exact middleware chain (helmetexpress.jsonexpress-mongo-sanitize)
against a live request:

  • Body { email: { $gt: "" }, name: "ok", nested: { "$where": "...", safe: 1 } }
    { email: {}, name: "ok", nested: { safe: 1 } } — operator keys stripped at
    every level, legitimate fields preserved.
  • Query ?filter[$gt]={ filter: {} }.
  • Response carried x-content-type-options: nosniff and x-frame-options: SAMEORIGIN
    from helmet.

…ware

The app relied entirely on per-handler validation to stay safe from
NoSQL operator injection, with no centralized safety net and no HTTP
security headers.

- Add helmet() early in the middleware chain to set secure response
  headers (X-Content-Type-Options, X-Frame-Options, HSTS, etc.).
- Add express-mongo-sanitize() after body parsing to strip keys
  containing $ or . from req.body, req.params and req.query, so an
  operator-shaped payload like { "email": { "$gt": "" } } can never
  reach a query as an operator object, regardless of the handler.

Both run before the routes, providing defense-in-depth without changing
any existing auth or notes CRUD behavior.

Closes niharika-mente#79
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@sricharan12-hub, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 26 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 01f16e77-7c87-41fe-9898-396fdc022543

📥 Commits

Reviewing files that changed from the base of the PR and between 87148ba and 6b19bcc.

⛔ Files ignored due to path filters (1)
  • backend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • backend/package.json
  • backend/src/server.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

Add global input sanitization and security headers (express-mongo-sanitize + helmet) as defense-in-depth

1 participant