Skip to content

fix: patch critical security vulnerabilities across the backend#3

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1780488372-security-fixes
Open

fix: patch critical security vulnerabilities across the backend#3
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1780488372-security-fixes

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Security audit found 12 issues (3 critical, 3 high, 3 medium, 3 low). This PR fixes all critical and high issues plus the medium ones.

Critical fixes

  • Removed console.log("DEBUG -> JWT_SECRET VALUE IS:", ...) from server.js — was leaking the JWT signing secret to stdout on every boot
  • Added startup validation — server now aborts with process.exit(1) if JWT_SECRET is unset, preventing tokens signed with undefined
  • Restricted CORS — replaced cors() (allow-all) with origin whitelist via CORS_ORIGIN env var

High fixes

  • Added helmet middleware for security headers (X-Frame-Options, Strict-Transport-Security, etc.)
  • Added express-rate-limit on /api/auth/login and /api/auth/register (20 req / 15 min per IP)
  • Added src/middleware/auth.middleware.js — JWT verification middleware for protecting future routes

Medium fixes

  • express.json({ limit: '10kb' }) — prevents large-payload DoS
  • morgan('combined') in production, 'dev' only in development
  • sequelize.sync({ alter: true }) only in development; plain sync() in production
  • User.name now has len: [1, 100] validator

Other

  • Added backend/.env.example documenting all required env vars
  • New deps: helmet, express-rate-limit

Not addressed (low risk)

  • Moderate uuid vuln in Sequelize transitive dep (no fix without breaking Sequelize major)
  • SQL injection: mitigated by Sequelize ORM parameterized queries

Link to Devin session: https://app.devin.ai/sessions/7704ba3bc578467684c493bdf9fb1b72
Requested by: @0xpritam

Summary by CodeRabbit

  • New Features

    • Rate limiting on authentication endpoints (20 attempts per 15-minute window)
    • Enhanced HTTP security headers and restricted CORS allowlist
    • Authentication token validation with clear 401 responses for missing/invalid tokens
    • User name validation tightened to 1–100 characters
  • Chores

    • Added environment variable configuration template

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR hardens backend startup and middleware: adds env templates and dependency entries, enforces JWT_SECRET at boot, introduces helmet and allowlist CORS (with credentials), limits JSON size, adds JWT authenticate middleware, rate-limits auth routes, and tightens User.name validation.

Changes

Backend Security and Authentication

Layer / File(s) Summary
Environment configuration and dependency additions
backend/.env.example, backend/package.json
Adds .env.example with server, DB, JWT, and CORS variables. Adds helmet and express-rate-limit to dependencies.
Server startup validation and environment handling
backend/server.js
Loads env early, enforces JWT_SECRET presence (fatal if missing), derives isDev from NODE_ENV, and uses sequelize.sync({ alter: true }) in development vs sequelize.sync() otherwise.
HTTP security middleware and request pipeline
backend/src/app.js
Adds helmet(); builds CORS allowlist from CORS_ORIGIN and allows no-origin requests; enables credentials; limits JSON body parser to 10kb; switches morgan between combined (prod) and dev.
JWT authentication middleware
backend/src/middleware/auth.middleware.js
New authenticate middleware verifies Authorization: Bearer <token> via jwt.verify with process.env.JWT_SECRET, sets req.user on success, and returns 401 JSON for missing/invalid tokens.
Rate limiting on authentication routes
backend/src/routes/auth.routes.js
Adds express-rate-limit authLimiter (15m window, max 20/IP, standardHeaders true) and applies it to POST /register and POST /login before controller handlers.
User model field validation
backend/src/models/user.js
User name field gains len: [1,100] validation with updated error message.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🐰 A rabbit hops through the code with glee,
Secrets guarded, CORS set free,
Rate limits bounce, auth flows with grace,
Middleware snug in its place!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: patch critical security vulnerabilities across the backend' directly and clearly summarizes the PR's main objective of addressing security audit findings.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch devin/1780488372-security-fixes

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/server.js (1)

34-37: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Exit the process when startup fails.

If sequelize.authenticate() or the new sync calls reject, the catch only logs and returns. The HTTP listener never starts, but the process can stay alive (DB pool/timers keep the event loop busy), masking the failure from orchestrators that rely on a non-zero exit to restart the container.

🛡️ Proposed fix
   } catch (error) {
     console.error('Failed to start server:', error);
+    process.exit(1);
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/server.js` around lines 34 - 37, The catch block that handles startup
failures currently only logs the error, so when sequelize.authenticate() or
model syncs fail the process continues running; update the catch to terminate
the process with a non-zero exit (e.g. call process.exit(1)) after logging the
error so orchestrators detect failure. Locate the try/catch around
sequelize.authenticate() and the sync/startup logic (the block that logs "Failed
to start server:"), and add a process.exit(1) (or equivalent shutdown/cleanup
then exit) in that catch to ensure the container exits on startup failure.
🧹 Nitpick comments (1)
backend/src/routes/auth.routes.js (1)

19-20: Confirm proxy/IP configuration for the rate limiter.

The limiter keys on client IP. If the app runs behind a reverse proxy/load balancer without app.set('trust proxy', ...), all requests will appear to originate from the proxy IP — throttling every client together — and X-Forwarded-For cannot be trusted. Set trust proxy to match your deployment (and keep it disabled/specific to avoid IP spoofing of the rate-limit key).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/src/routes/auth.routes.js` around lines 19 - 20, The rate limiter
(used on router.post('/register', authLimiter, register) and
router.post('/login', authLimiter, login)) keys requests by client IP; ensure
your Express app sets trust proxy appropriately for your deployment so
X-Forwarded-For is honored (e.g. app.set('trust proxy', 'loopback' or the
specific proxy CIDR) or disable when not behind a proxy) to avoid all clients
sharing the proxy IP; update the app initialization to call app.set('trust
proxy', ...) with a specific value matching your load balancer/reverse proxy and
document/guard this setting to prevent enabling trust for arbitrary clients.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/src/middleware/auth.middleware.js`:
- Around line 15-16: The jwt.verify call in the auth middleware should be
restricted to the expected algorithm to avoid accepting other HS* variants:
update the jwt.verify(token, process.env.JWT_SECRET) invocation in
auth.middleware.js to pass verification options specifying algorithms: ['HS256']
(matching the signing in auth.controller.js) so only HS256-signed tokens are
accepted; keep the rest of the try/catch flow unchanged.

In `@backend/src/routes/auth.routes.js`:
- Around line 8-17: Replace the deprecated/compat `max` option with the current
`limit` option in the rateLimit configuration used to create authLimiter (i.e.,
change the property on the rateLimit call that constructs authLimiter). Also
ensure your Express app is configured to respect upstream proxies by setting
app.set('trust proxy', ...) in your app bootstrap/init code so rateLimit keys
off the real client IP rather than the proxy; keep the existing
standardHeaders/legacyHeaders/message settings unchanged.

---

Outside diff comments:
In `@backend/server.js`:
- Around line 34-37: The catch block that handles startup failures currently
only logs the error, so when sequelize.authenticate() or model syncs fail the
process continues running; update the catch to terminate the process with a
non-zero exit (e.g. call process.exit(1)) after logging the error so
orchestrators detect failure. Locate the try/catch around
sequelize.authenticate() and the sync/startup logic (the block that logs "Failed
to start server:"), and add a process.exit(1) (or equivalent shutdown/cleanup
then exit) in that catch to ensure the container exits on startup failure.

---

Nitpick comments:
In `@backend/src/routes/auth.routes.js`:
- Around line 19-20: The rate limiter (used on router.post('/register',
authLimiter, register) and router.post('/login', authLimiter, login)) keys
requests by client IP; ensure your Express app sets trust proxy appropriately
for your deployment so X-Forwarded-For is honored (e.g. app.set('trust proxy',
'loopback' or the specific proxy CIDR) or disable when not behind a proxy) to
avoid all clients sharing the proxy IP; update the app initialization to call
app.set('trust proxy', ...) with a specific value matching your load
balancer/reverse proxy and document/guard this setting to prevent enabling trust
for arbitrary clients.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 40fdd1ad-c152-40af-ba2b-c376f0c832bb

📥 Commits

Reviewing files that changed from the base of the PR and between 44f8626 and ea0d7ed.

⛔ Files ignored due to path filters (1)
  • backend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • backend/.env.example
  • backend/package.json
  • backend/server.js
  • backend/src/app.js
  • backend/src/middleware/auth.middleware.js
  • backend/src/models/user.js
  • backend/src/routes/auth.routes.js

Comment on lines +15 to +16
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

jsonwebtoken 9.x jwt.verify algorithms option default behavior

💡 Result:

In jsonwebtoken version 9.x, the jwt.verify function does not accept unsigned tokens ("alg": "none") by default [1]. If you need to verify an unsigned token, you must explicitly include 'none' in the algorithms option [1]. When the algorithms option is not specified, jwt.verify defaults to a list of allowed algorithms based on the type of key provided [2][3]: - Secret (HMAC): ['HS256', 'HS384', 'HS512'] [2][3] - RSA: ['RS256', 'RS384', 'RS512'] [2][3] - EC (Elliptic Curve): ['ES256', 'ES384', 'ES512'] [2][3] - Default (if key type cannot be inferred): ['RS256', 'RS384', 'RS512'] [2][3] To verify an unsigned token, you must pass { algorithms: ['none'] } in the options argument [1]. It is strongly recommended to always explicitly specify the expected algorithms to prevent security vulnerabilities, such as algorithm confusion attacks [2][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the auth controller and the middleware file mentioned in the review
rg -n "jwt\\.sign\\(" backend/src --hidden || true
rg -n "JWT_SECRET|jwt\\.verify\\(" backend/src/middleware/auth.middleware.js backend/src || true

# Print the relevant sections with line numbers (keep output small)
echo "---- auth.controller.js jwt.sign context ----"
for f in $(fd -t f "auth.controller.js" backend/src -a 2>/dev/null || true); do
  echo "FILE: $f"
  sed -n '1,220p' "$f" | nl -ba | sed -n '1,220p'
done

echo "---- auth.middleware.js jwt.verify context ----"
if [ -f "backend/src/middleware/auth.middleware.js" ]; then
  sed -n '1,120p' backend/src/middleware/auth.middleware.js | nl -ba | sed -n '1,120p'
fi

Repository: 0xpritam/SmartQueue

Length of output: 605


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- backend/src/controllers/auth.controller.js around jwt.sign ----"
sed -n '70,130p' backend/src/controllers/auth.controller.js | cat -n

echo "---- backend/src/middleware/auth.middleware.js around jwt.verify ----"
sed -n '1,80p' backend/src/middleware/auth.middleware.js | cat -n

Repository: 0xpritam/SmartQueue

Length of output: 2772


Pin the expected algorithm in jwt.verify.

auth.controller.js signs with a symmetric secret but does not specify an algorithm; jsonwebtoken will default to HS256 for signing, while jwt.verify currently accepts multiple HS* algorithms. Restricting verification to HS256 prevents accepting tokens signed with unexpected algorithms.

🔒 Proposed change
-    const decoded = jwt.verify(token, process.env.JWT_SECRET);
+    const decoded = jwt.verify(token, process.env.JWT_SECRET, { algorithms: ['HS256'] });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET, { algorithms: ['HS256'] });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/src/middleware/auth.middleware.js` around lines 15 - 16, The
jwt.verify call in the auth middleware should be restricted to the expected
algorithm to avoid accepting other HS* variants: update the jwt.verify(token,
process.env.JWT_SECRET) invocation in auth.middleware.js to pass verification
options specifying algorithms: ['HS256'] (matching the signing in
auth.controller.js) so only HS256-signed tokens are accepted; keep the rest of
the try/catch flow unchanged.

Comment on lines +8 to +17
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 20, // 20 attempts per window per IP
standardHeaders: true,
legacyHeaders: false,
message: {
success: false,
message: 'Too many requests, please try again later.',
},
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

express-rate-limit v8 max option deprecated limit

💡 Result:

In express-rate-limit, the max option is not deprecated in the sense of being removed; rather, it has been superseded by the limit option [1][2]. The option was renamed from max to limit starting in version 7.x to better align with IETF standard draft terminology [2][3]. The package continues to support max for backwards compatibility, meaning existing code using max will still function as expected [1][2]. However, the limit option is the current, preferred configuration property [4][5]. It is recommended to update your configuration to use limit to ensure future compatibility and avoid linter warnings [5]. Additionally, note that the behavior of setting this value to 0 changed in version 7.0.0: whereas it previously acted as a "disable" flag, it now blocks all requests to the endpoint [1][2]. To disable the rate limiter, you should use the skip function instead [6][2].

Citations:


Switch express-rate-limit from max to limit (and ensure correct client IP behind proxies)

express-rate-limit uses limit as the preferred configuration name; max is kept only for backwards compatibility, so updating avoids future tooling/lint noise and aligns with the current API.

♻️ Proposed change
   windowMs: 15 * 60 * 1000, // 15 minutes
-  max: 20, // 20 attempts per window per IP
+  limit: 20, // 20 attempts per window per IP

Also, if this service is behind a reverse proxy (Nginx/ELB), configure app.set('trust proxy', ...) so rate limiting keys off the real client IP (otherwise it may throttle the proxy IP for everyone).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/src/routes/auth.routes.js` around lines 8 - 17, Replace the
deprecated/compat `max` option with the current `limit` option in the rateLimit
configuration used to create authLimiter (i.e., change the property on the
rateLimit call that constructs authLimiter). Also ensure your Express app is
configured to respect upstream proxies by setting app.set('trust proxy', ...) in
your app bootstrap/init code so rateLimit keys off the real client IP rather
than the proxy; keep the existing standardHeaders/legacyHeaders/message settings
unchanged.

- Remove debug console.log that leaked JWT_SECRET to stdout
- Add startup validation to abort if JWT_SECRET is unset
- Restrict CORS to explicit origins via CORS_ORIGIN env var
- Add helmet middleware for security headers
- Add express-rate-limit on /api/auth routes (20 req/15min)
- Add JWT auth middleware (src/middleware/auth.middleware.js)
- Limit express.json body to 10kb to prevent DoS
- Use morgan('combined') in production, 'dev' otherwise
- Only run sequelize.sync({ alter: true }) in development
- Add max-length (100) validation on User.name
- Add .env.example with required environment variables

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration
devin-ai-integration Bot force-pushed the devin/1780488372-security-fixes branch from ea0d7ed to 99ed34f Compare June 3, 2026 12:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/.env.example`:
- Line 10: Replace the empty DB_PASSWORD value in the example env with a
non-empty placeholder (e.g., a descriptive token like "CHANGE_ME_DB_PASSWORD" or
"YOUR_DB_PASSWORD") so the example discourages using empty/blank database
passwords; update the DB_PASSWORD entry in backend/.env.example accordingly.
- Line 13: Update the JWT_SECRET placeholder in .env.example to clearly require
a strong HS256 secret: replace the generic "change-me" value with a descriptive
placeholder and add a comment above JWT_SECRET explaining it must be at least
256 bits (≥32 random bytes) or a base64-encoded 32+ byte value, generated from a
CSPRNG; reference the JWT_SECRET variable so reviewers can find and verify the
change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ae551bde-8794-4b73-9e78-1a83e9ad66a8

📥 Commits

Reviewing files that changed from the base of the PR and between ea0d7ed and 99ed34f.

⛔ Files ignored due to path filters (1)
  • backend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • backend/.env.example
  • backend/package.json
  • backend/server.js
  • backend/src/app.js
  • backend/src/middleware/auth.middleware.js
  • backend/src/models/user.js
  • backend/src/routes/auth.routes.js
🚧 Files skipped from review as they are similar to previous changes (5)
  • backend/src/middleware/auth.middleware.js
  • backend/src/models/user.js
  • backend/src/routes/auth.routes.js
  • backend/src/app.js
  • backend/server.js

Comment thread backend/.env.example
DB_PORT=3306
DB_NAME=smartqueue
DB_USER=root
DB_PASSWORD=

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a placeholder password to avoid encouraging empty passwords.

The empty DB_PASSWORD value, even in an example file, may encourage developers to run local environments without passwords, creating a security gap.

🔒 Proposed fix
-DB_PASSWORD=
+DB_PASSWORD=your-secure-password-here
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
DB_PASSWORD=
DB_PASSWORD=your-secure-password-here
🧰 Tools
🪛 dotenv-linter (4.0.0)

[warning] 10-10: [UnorderedKey] The DB_PASSWORD key should go before the DB_PORT key

(UnorderedKey)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/.env.example` at line 10, Replace the empty DB_PASSWORD value in the
example env with a non-empty placeholder (e.g., a descriptive token like
"CHANGE_ME_DB_PASSWORD" or "YOUR_DB_PASSWORD") so the example discourages using
empty/blank database passwords; update the DB_PASSWORD entry in
backend/.env.example accordingly.

Comment thread backend/.env.example
DB_PASSWORD=

# Auth
JWT_SECRET=change-me-to-a-strong-random-value

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Strengthen the JWT_SECRET placeholder to convey minimum security requirements.

The generic placeholder doesn't communicate that JWT HS256 secrets should be at least 256 bits (32+ random bytes). A weak secret undermines the entire authentication system.

🔐 Proposed fix
-JWT_SECRET=change-me-to-a-strong-random-value
+JWT_SECRET=use-at-least-32-random-bytes-base64-encoded-minimum-256-bits

Or add a comment above:

+# JWT_SECRET must be at least 256 bits (32 bytes). Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
 JWT_SECRET=change-me-to-a-strong-random-value
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
JWT_SECRET=change-me-to-a-strong-random-value
JWT_SECRET=use-at-least-32-random-bytes-base64-encoded-minimum-256-bits
Suggested change
JWT_SECRET=change-me-to-a-strong-random-value
# JWT_SECRET must be at least 256 bits (32 bytes). Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
JWT_SECRET=change-me-to-a-strong-random-value
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/.env.example` at line 13, Update the JWT_SECRET placeholder in
.env.example to clearly require a strong HS256 secret: replace the generic
"change-me" value with a descriptive placeholder and add a comment above
JWT_SECRET explaining it must be at least 256 bits (≥32 random bytes) or a
base64-encoded 32+ byte value, generated from a CSPRNG; reference the JWT_SECRET
variable so reviewers can find and verify the change.

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