The LMS Backend applies several security controls globally inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Pragyat-Nikunj/Learning-Management-System-backend/llms.txt
Use this file to discover all available pages before exploring further.
index.js before any request reaches a route handler. These are not opt-in per endpoint — they run on the entire application. As an API consumer you need to be aware of these controls because they shape which requests succeed, which are rejected, and how your client must be configured to communicate with the API correctly.
Security middleware stack
The controls are applied in this order at startup:index.js
Helmet
Sets a collection of HTTP response headers that protect against common web vulnerabilities:
X-Content-Type-Options, X-Frame-Options, Strict-Transport-Security, Content-Security-Policy, and others. Applied to every response without configuration.HPP
HTTP Parameter Pollution protection. When duplicate query string parameters are submitted (e.g.
?role=student&role=admin), HPP picks the last value and removes duplicates so controllers always receive a scalar, not an array.Mongo Sanitize
Strips MongoDB operator keys (those starting with
$) from req.body and req.params before they reach any controller. This prevents NoSQL injection attacks where an attacker might submit { "email": { "$gt": "" } } to bypass authentication.Rate Limiting
Limits each IP address to 100 requests per 15-minute window across all
/api/* routes. Exceeding the limit returns a plain-text error message rather than a JSON response.Rate limiting
The limiter is configured as follows and mounted on/api:
index.js
429 Too Many Requests and the plain-text message "Too many request from this IP, please try later". The window resets 15 minutes after the first request in that window.
CORS policy
Cross-Origin Resource Sharing is configured to allow requests only from a specific origin. The allowed origin is read from theCLIENT_URL environment variable, defaulting to http://localhost:5173:
index.js
credentials: trueis required on the server side so that thetokencookie is included in cross-origin responses. Your client must also setcredentials: "include"on everyfetchcall (orwithCredentials: truein Axios) to send and receive cookies cross-origin.- Only the origin set in
CLIENT_URLis allowed. Requests from any other origin will be blocked at the preflight stage. - The full allowed method set is
GET,POST,PUT,DELETE,PATCH,HEAD, andOPTIONS.
Body size limits
To reduce the risk of request body attacks and memory exhaustion, JSON and URL-encoded request bodies are capped at 10 kb:index.js
413 Payload Too Large error before reaching any controller. This limit applies to JSON and form-encoded bodies — it does not apply to file uploads, which are handled separately by Multer.
Stripe webhook raw body parsing
The Stripe webhook endpoint requires the raw, unmodified request body for signature verification. A special raw body parser is mounted before the global JSON parser to intercept only that path:index.js
POST /api/v1/payments/webhook receives a Buffer on req.body instead of a parsed object. Do not send manually crafted JSON to this endpoint — it is intended solely for Stripe’s webhook delivery system.
The order of middleware registration in
index.js matters. The raw body parser for /api/v1/payments/webhook is mounted before express.json() so that Express does not parse the body before Stripe can verify its signature.Security controls summary
| Control | Scope | Behaviour |
|---|---|---|
| Helmet | All routes | Sets secure HTTP response headers |
| HPP | All routes | Collapses duplicate query parameters to the last value |
| Mongo Sanitize | All routes | Strips $-prefixed keys from req.body and req.params |
| Rate limiter | /api/* | 100 requests per IP per 15-minute window; returns 429 on breach |
| CORS | All routes | Restricts origin to CLIENT_URL; requires credentials: include |
| JSON body limit | All routes except webhook | Rejects bodies larger than 10 kb |
| URL-encoded body limit | All routes except webhook | Rejects bodies larger than 10 kb |
| Raw body parser | /api/v1/payments/webhook only | Passes raw Buffer for Stripe signature verification |