Skip to content

fix(auth): harden session cookie, strip password from req.user, change logout to POST#575

Closed
anshul23102 wants to merge 1 commit into
GitMetricsLab:mainfrom
anshul23102:fix/session-security-554-555-556
Closed

fix(auth): harden session cookie, strip password from req.user, change logout to POST#575
anshul23102 wants to merge 1 commit into
GitMetricsLab:mainfrom
anshul23102:fix/session-security-554-555-556

Conversation

@anshul23102
Copy link
Copy Markdown
Contributor

@anshul23102 anshul23102 commented May 27, 2026

Summary

Fixes three independent security issues in the backend authentication layer.

Fix 1 - Session cookie hardening (#554)

express-session was configured with no cookie options, so the session cookie was issued with browser defaults (no httpOnly, no Secure, no SameSite).

Changes in backend/server.js:

  • Added httpOnly: true so JavaScript cannot read the cookie (XSS session hijack prevention)
  • Added secure: isProduction so the cookie is only sent over HTTPS in production
  • Added sameSite: 'strict' so the cookie is not sent with any cross-origin request (CSRF prevention)
  • Added maxAge: 24h as an explicit TTL

Fix 2 - Remove password hash from req.user (#555)

deserializeUser called User.findById(id) with no field projection, attaching the full Mongoose document (including password) to req.user on every authenticated request.

Changes in backend/config/passportConfig.js:

  • Added .select('-password -__v') to exclude the bcrypt hash and internal version key
  • Added .lean() to return a plain object instead of a Mongoose document, preventing accidental exposure of model methods

Fix 3 - Change logout from GET to POST (#556)

GET /api/auth/logout is exploitable via CSRF: any third-party page can embed <img src=".../logout"> to silently sign out authenticated users.

Changes in backend/routes/auth.js:

  • Changed router.get to router.post
  • Added req.session.destroy() to fully invalidate the server-side session
  • Added res.clearCookie('connect.sid') to remove the cookie from the browser

Test Plan

  • Login, verify session cookie has httpOnly, Secure (production), and SameSite=Strict attributes in browser DevTools
  • Confirm req.user in any route handler does not contain a password field
  • Confirm GET /api/auth/logout returns 404; POST /api/auth/logout returns 200 and cookie is cleared

Important

GSSoC'26 contribution - Please add relevant labels (gssoc26, level:intermediate, type:security) to help with point tracking. Thank you!

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced logout functionality to properly clear sessions and remove authentication tokens.
    • Strengthened session security with improved cookie protection settings, including protection against cross-site attacks.

Review Change Stack

…e logout to POST

Fixes GitMetricsLab#554 - Add httpOnly, Secure, and SameSite=strict to the session cookie
so the token is inaccessible to JavaScript and cannot be sent in cross-origin
requests. The Secure flag is conditioned on NODE_ENV=production to keep
local development functional over HTTP.

Fixes GitMetricsLab#555 - Pass .select('-password -__v').lean() to deserializeUser so the
bcrypt hash is never attached to req.user. Using .lean() also returns a plain
object instead of a full Mongoose document, preventing accidental exposure of
model methods on the request context.

Fixes GitMetricsLab#556 - Change the logout endpoint from GET to POST. GET is a safe,
idempotent method that browsers trigger automatically (img src, link prefetch,
CSS url). Any third-party page could embed a zero-pixel image pointing at the
logout URL to silently sign out authenticated users. POST requires an explicit
fetch or form submission, which CORS and SameSite=strict will block from
cross-origin callers. The handler now also calls req.session.destroy() and
clears the cookie to ensure the session is fully invalidated server-side.
@netlify
Copy link
Copy Markdown

netlify Bot commented May 27, 2026

Deploy Preview for github-spy ready!

Name Link
🔨 Latest commit 893e135
🔍 Latest deploy log https://app.netlify.com/projects/github-spy/deploys/6a170633636c8600083b656c
😎 Deploy Preview https://deploy-preview-575--github-spy.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

Warning

Review limit reached

@anshul23102, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 50 minutes and 16 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

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.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 179e99de-6f3e-4494-b33c-307b11586a8d

📥 Commits

Reviewing files that changed from the base of the PR and between 4ae0ef6 and 893e135.

📒 Files selected for processing (3)
  • backend/config/passportConfig.js
  • backend/routes/auth.js
  • backend/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 and usage tips.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":401,"request":{"method":"PATCH","url":"https://api.github.com/repos/GitMetricsLab/github_tracker/issues/comments/4555728713","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nThree backend authentication and session security improvements: session cookies now enforce httpOnly, strict sameSite, and production-aware secure flags; user deserialization excludes password and version fields to prevent exposure; and logout migrates from GET to POST with explicit session destruction and cookie clearing.\n\n## Changes\n\n**Session and Authentication Security Hardening**\n\n|Layer / File(s)|Summary|\n|---|---|\n|**Session cookie security configuration** <br> `backend/server.js`|Session middleware cookie configuration explicitly sets `httpOnly`, `sameSite: 'strict'`, and conditionally enables `secure` based on production environment, while preserving existing session options and 24-hour `maxAge`.|\n|**User deserialization with field projection** <br> `backend/config/passportConfig.js`|`passport.deserializeUser` now projects user documents to exclude `password` and `__v` fields using Mongoose select syntax and `.lean()` to return plain objects, preventing bcrypt hashes from reaching `req.user` or being serialized in API responses.|\n|**Logout endpoint POST with session cleanup** <br> `backend/routes/auth.js`|Logout endpoint migrates from GET to POST and implements explicit session teardown: calls `req.logout`, destroys the session via `req.session.destroy`, clears the `connect.sid` cookie, and returns JSON responses with distinct error handling for logout and session cleanup failures.|\n\n🎯 3 (Moderate) | ⏱️ ~22 minutes\n\n## Possibly related issues\n\n- GitMetricsLab/github_tracker#554: PR directly addresses missing session cookie configuration (`httpOnly`, production-aware `secure`, `sameSite: 'strict'`, `maxAge`) reported in this issue.\n- GitMetricsLab/github_tracker#373: PR implements exact session cookie security hardening (`httpOnly`, `sameSite`, production-conditional `secure`) proposed in this issue.\n- GitMetricsLab/github_tracker#556: PR implements all requested fixes—logout GET→POST migration, `req.session.destroy()` and `res.clearCookie('connect.sid')` calls, and session cookie security flags.\n- GitMetricsLab/github_tracker#447: PR addresses same session security concerns through hardened cookie flags in `backend/server.js` and logout improvements in `backend/routes/auth.js`.\n\n## Possibly related PRs\n\n- [GitMetricsLab/github_tracker#467](https://github.com/GitMetricsLab/github_tracker/pull/467): Both PRs harden session cookies in `backend/server.js` with `httpOnly`, `sameSite: 'strict'`, and production-conditional `secure` flag.\n\n## Suggested labels\n\n`level:intermediate`, `quality:clean`, `gssoc:approved`\n\n## Poem\n\n> 🐰 A rabbit hops through secure session gates,\n> passwords hidden from prying eyes and spies,\n> cookies now guarded with `sameSite` mates,\n> logout posts cleanly beneath summer skies,\n> session strings vanish with one final rise.\n\n</details>\n\n<!-- walkthrough_end -->\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 5</summary>\n\n<details>\n<summary>✅ Passed checks (5 passed)</summary>\n\n|         Check name         | Status   | Explanation                                                                                                                                        |\n| :------------------------: | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------- |\n|         Title check        | ✅ Passed | The title accurately summarizes all three main security fixes: session cookie hardening, password removal from req.user, and logout method change. |\n|      Description check     | ✅ Passed | The description is comprehensive, covering all three security fixes with detailed explanations of the vulnerabilities and solutions.               |\n|     Docstring Coverage     | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.                                         |\n|     Linked Issues check    | ✅ Passed | Check skipped because no linked issues were found for this pull request.                                                                           |\n| Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request.                                                                           |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=GitMetricsLab/github_tracker&utm_content=575)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n<!-- internal state start -->\n\n\n<!-- DwQgtGAEAqAWCWBnSTIEMB26CuAXA9mAOYCmGJATmriQCaQDG+Ats2bgFyQAOFk+AIwBWJBrngA3EsgEBPRvlqU0AgfFwA6NPEgQAfACgjoCEYDEZyAAUASpETZWaCrKPR1AGxJcAZvAAeABRoeLAAlFywzkpYiNKI8PhYTPgA1vAkADT2uBTw3DxoiIgA7vgU9D4ULJAUJACOGthxFNkMURikkB74RPh4kATWAPIAytCQkAYAco4ClFwArADsi5CAKASQo/0UDN6Qfv4A9HHFiRhgcQzYebiyYIuLACwPj68AbJCASYQwzqSckGY2iwUwAgqFylxMIhYNgPAAmADMAEYAAzwjZbXDUZpcfDcMiYgDCdWodC48PR7zAqMWYHhy2gyKeHEW7w4TwAHAAtSYGACqNgAMpFcLhuIgOEcjkR1LCBBomMwjgBxdQAWRIuXgDEQQpUMrl2AEAH1cmgGKlKEduHCPEcVosjKNHECXPwfIwOqRkIEBBarRhaBEDFAAGIBSDIzGjeLnBRpDKQKIVMjwTqQQJ1Dxk+hDMyPJ5hAyTcPwLxcf2Wsi0E6UKQUDRCRAl3SQUG0JT0U4JJIJ9IkfjccRJSXJsXcYYYDyyLi5bBZeyiG77JBWaq0bBic7ZRBoNijdT7ADkiG1YmP2Uw9CB/lBpApT1gGlDkAj/kgGM2NhIzHwUkKYoygqZMilgA5qmYWoGiaFpM2zXNBnwSAC0eYtSzfct9irQNayYDA/CIG0ikQbhylwIkkkIpsWwwgBJLAlBaeA0A8eAAC8SH5For07OhIA0OIvDEQJjzAbgSOA+gwBNE0JGPMJ0CDASvEwQJFJKWBCR6NBaHTIhBi0yBmkoF8yw/RFiW9Qcej6AYqhqFUAFEJiGKwxgmLMSBzGg82Q1D3nQtsIwrSAcJrI5qjwaQjhCXBn2bVsoCJaz6CimgIJqdLTP+JDan6GhGzIs8AG50D4tKYJ7c4NCY3J8FkdSlMqxBFVUihKMTEhRPw8gxEE+BaAUvKfDteR0wkVjBrJJczlHF8DGgaRcB4HMMA4V8ADVKHgHx5GqvsUgHUDkFgCcpxnbJY2uOpM3THgNy3EcMDCK9lNGfcSEPGgAF5RnPFb7oEaoSjggAREgJGgfB8A8ZA0B8Qrul6dMzMgSiCPgCgoLqRoTL4Wh8GkSAMHwFb8Oxe60EA0pykqDIPHoe7stAoMvAoVrXwxvxscgZyJli7h4Fi0IjlsgroNwG4MGQJ5USeMr3PGSBBeFuLYDF3oJbqKWKBlz9UVRZrGHa5B4sHI6MgWjs9Oe1iSbJwd7tsMLFFnaD6gXM88t0+gc3mOGDnKPnRm2Ilj3hT5zUtfTMyIYp8AYSPsi8KQPA4dNCrYPSyWyO4CQ4K4bnUWQwgW/RjHAKAaw9HACGIMhlF8hRWHYLheH4YRRHEKQZHkJglCoVR1C0HQK5MKA4FQVBMDrwhSHIKhm6VNgMABKgSnsV1nHkOQFEHlQ1E0bRdDAQxK9MAxwqDI58MI4jijIigKKo+AiBojaACJv4MCx2zohui9EIOCcO6fAnp2iYB9EYAABhJR+5FarSB2lNTi3FKAwIdpvHStAzZGXxpAEocp0AHAZvQXg+ARDbj7PFagkASD+AYB4bATFDKDjgZJOmmDryQHVEkPo+A4iQBgbJCQmCGy9iwH4bytA3pMxWqUdQ7RiZDBgRoVSGB1KYMQMhc20EHAeEBvDVawJO5UJWkvLSfBaFYGpqNDwHheH8JhkIwm1xV6aBgEZPwXhyq4KUvQ/w3A1rUHKP3FgHicjUFjnohhTCWH8Q4UBLhpCZEPUhuwGQDAXDDhOlpZADkoLzFjtQbEyi/LCNxrBDBxsLQMEGuwViM4lx5FQfxe6oIrB0X0WRGW0gFrmEsKCQxTdzhm10UZJQTDnDRNHLXBhT9m7B1tAINiDB6Fr3UBkFsr5pjIQWeROgNpjRrI2eIO49g34YBxHUZAkDOjtKwDA6+eFX5EXgaRci3M340TUUYf5f91SYF2stTCvjQTXJnJxCgRghTpmJvc0gtAuAAGonhHDAMiIwTkzzwCBMvRQg46gSAyJvEgPgfDkS4JqPSjgDDf0/kYCAYAjAvMigVGK6sP70p/n/UEACF5N34iAt08hwFeigdINwRlxYDBrGRTOhCigSoeZUSCJD+b5Wij7EYysWY8LqMBK0FT5hikoAoNe1RHHq3YDqYBcYaEkGiPgEoGANBeMHOQTeHRaDs0YE05AMCqmytwNw5S5ssALLWZ4eQdVqiyDwYOA6WASXUyDVVB1bq40NRgW0U2bDhG9W7gNWgmDLaLgNVqaWyAHAMD2MUI4PhtDMNugAKVGMMaYhDiF/luqRUQu0dT0IoNUPgbBihoB9EHPgIbjbJpNk6jA2BuDurgIOXgkNEjNBQMwYJv5GnPWMnEegabsqNn+IET+ms7K4E/mETBPq/W0JWkkZpDAmmJODVrPAYbKq63ICey5u7fG1vrcgW5vShFEPihLbNsgYlGXncHJhTq8gZj0eWgZv8hkjKXmMvKeipk5jw3M8VBzn78WWScodtrxBStfDYDlgItSwEUCqpFKAnlsuyogEW8VflcCDRy89WpL3XoKp/bIGhpP3u+JU4TGhiq4DEyGyTAkZMwNfEKb9K15hRBJch1KUIKqBOCTqdQlSM1zSzcteNgRpMaFkzw9NrUUPOE6gOHqSQ+qaASENJziNzXpsaCG+zGnONnidfQcVr75A62liUnpo4nYywaZZkLOmwuOc0wYOF5A7lGcgCi5EyIMXwmxbi/F/EB5Es3SQMlFKqWQAABJv1gDyxloZL5spaA2blDLsP/0AUK7s28wEQOsjs/k3BaBkmQE5IJtya2ZsBINX19XnAWzeTcWZWA96Z0evUjMs8YFrkO89TBPgcwGR4c0WOFmhj4VtucJp+0tQFvneWwAmASBqLnUbhYo8gCGiquxDK3y0WsIjtw9pMyVBOjbgZpcRcCBrOuKC6shMFDHnIuGBe4DxHix8hGBp4AbHlzcbHWwJjHwheKxm4wjbz3hIJgzSWFIBWhIELdDRkGFIHEBmJDw58OBBc2gKQvhWJxAp3j8XXEMDpi2W05FBwpcs8Ujw/8ygHHoG4NwOs1mjhWBIoszjSu2LsV2wcHom9sAYERXQLDfLcO7fGQWojMznrIDI0Ew50W+ArNObR7ZRg9nkAWnlhFhWUWcgxaiCr4gqv0Bq9BEl9X6GNeflwVrRB2sDa6+fCeGzouejivPRuS9qsRLbrUNAm8RU7zCuEg+w9j5jzPgYIvU9kAz1sXgcvQCCWtzXlwJQlMvDJ8JWFHolot6gLi5Kvu+9lCt9Hqfc+ABtAA3p/KgDy6K0E/hwXfkqTTvAAJzIkRGgWkPhOTwk5O8STn8JLxSP5/Nld834P0+c/b579mxn8zxnBcBI8j9ERORMhP4awwCOREQoCG8XB38klf9NAmIUELcuIWhMFUBl1Ztm4hgo1TFNJ5AUCpJtF6dGYwpBw4lmEuw5EUByZJsC0YF0FGw/AgwAAhWQA/MtJpPKISbuYRcSThCoX9YQ0RVnBAXxO7DMNRDRLRPKeLPWEhYJUxQQcxDQZ/GrTgmfVISiYDPnO4d/G3T+AAX0yB3z31IAP3f2sJIBNERFRHP1RFoEWERCeBvxIEWGf1f1gHf0/zeR/0WX/xoiAOxGflgKeCeCgJgPhSPyeEWAQLG1kHfzXWEUJnIBwIwAkETit1h2gj2EkBUSMgoXMSOQ0X0ThBWlF3xlZ2IVoISXphkUQEUksXNRsRIXsUcT4U6BcUHDcUcHYDKkoFHVZl9VjjqCBHTETXsE+i0KgJ0L0IML3X8BLhMJdXMMsJP330P2P3sLPwZGWBIGWGRHPxIFRBIHhF8OoH8OP24w5V4y5UAIQIiNAPiI4ERHP1iKDFgMeGSPn3fx/DUPrQLV4ESD4H5jAH9GPWEXEx/XGL9Wg3AmpiVmgGhKKHaUMI8St2fR4EoEpWxkDS/RvQpwjUgDg1mOTTzVQ1mJgSLX6j8zLRhgHAYLiCDGQHbU7SSz6UQDKnTHiVYTiAkkr2HTGMfVjkJORhvVV3LBXHhmUk+w0WXVlJbX6W0MJV0MTn0JYFWPWOP2zngEcC2KsMlVsP2NPzcOZE5ERHeDZERDrRuLf3uIDAil61MheM/mAMiI+JRB+NoCiPhABNFXfxtgVOETO0UCenOGZJlmxDXmNjwLmxYIWSW0uEzWZK6iXDFH0jd2R2ET+xZzCkxOiyeWmGGDBichNCcmmE2kgB+gbMgGPAoU3GoQwHJwYMIPh3M0R3kDIEJL2GETR0nGnEx2NllwJxoC4FJzyAvCkPZw3V6wQxoLWNxQzAhxgSZ1IDUQ1KUC1MtBWK8DWOMINLoCNOYHMIAF0L5q5lJxUy9htK9J9h8AQx9m0q8lBp9tS59RVa8Hkl8ash4j419x4q4W5mB1ATRBpEATRiVSU6ATRvSVoK5O8wLORz9EQSAr9Fgk5lh4Qk4GAfAGABBTiUQ0Bjjz93gngBA5Z5ZaAfBaBERaBUR3hBwUKi8V5ILoLYK6sSgEKa5QKIB0kTQ2AKBSATRlFLQYKkL18jAt9WxP41wbB9zjUDCPErBBFfIj9Vc4YsgFKkBhgGw8g+IMBtKm1dLMgFK3Ezw0MiBKIGxJ0SAGJCpIV/oyRtKt8LCFKasbBD51AAB1aoGgdcdwRHEgMytXSyyYL0yg2gFS2wCKiyqywaGwO3MGROf6WyxAFKUQVIbSnHKKyAT+PSWgVKjAUKrwHKy0fKigBcQq4qlKtK6QbJfIZ6KqvKucWqvS6KtiDAY1OiYoL2TK7S7+eqnMM8dqn8AxFHbSjfVsSYeSyYJaoqyS1IaYT6Eaiqi2LSaqwq5ar07EKWRAGquq+apa6A+HTAXbTaoyc5XxOpaHbyfaMbDiYmfg+KOoQcaY2IZcW4eQQ4aQLgT7FkpMFMGIfSbID5KSaCP8SaRxQpD2apVoY2WdNgGDZPayBYs66Kv8JQEakoZwBXToSTbGoquoL/IgFcRKuIPa868oN+dMVidq9atgEau68Ks6ry5axa5alanatajargT+CGRAFq4XQ6fmkm3moq4Ao6k67q3mi6tQ65Z6G6gY5qvIcWrAVAJUDdLSVLKQNoLXWy9AHXD6kgJNX6kuUhfwYmZEikrUd8+gIglW/DcVPRCQOEIBNQNiOjBU7sWGPAMZLG6Wz+XG8KoWgmvWfSKWxW8m7bOoamhW/a+m2USFZmwWoqpiMW1Wzm2mnm/a1almiOoq9K3UbUDMey5QUgWO/a2W5oeW2m6Kl266oWvZA4O3NsgpfoZSe6DDVKUhLwN3SGVibAGaayiugyJgBy0gd1UYdIPXWOCek26e6u7a3KkOuO6QQO1WoWwKo8CkxOGy3M6dAtUae3L3VbM4HnX8AQ6JRAPaAtVeqgLoc2mEWGWgTe/a8O/GwmmOpuoq1OxmjwDO1moW5e3MxlZarmpagu86ouzOz+PLY1SAAahwKPXK2u86+u46zq060Olu3eoq9q+wBegkegeYd9EyB2bodMFBpAdB5APi26SlO3SoYOeKVAW0HXXGL2TQLBnGwlX+6O4mgBz+IB9O/m4uka3q/qwa6QUEYoeIDxKBpamBha0mz+BBsBoq4YAYcVUYJgAkdGZg1agRmWw6huvB5O86wh84EakhxAMh/iShkIIRUmWhvq9peRphygQcVh5SKUzh5AbhxxXh5aL+86n+yOv+0RzRiRpmqRxBgqYYHwQx/EEgFKRfRRnsFRzm1sS8saooXAWwEWnO+xoW842gZYJ4d4OtHwRYEgd4NAc/TkHwC2hgZEd4AQeESkZYBgTkVEHp1wxIhgC/TkAQB0kgTC+EHwFEeEAQVp94d4BitAd4TkclVEZEWOz+cakpmwLakagQei8/TwnCy4xYSiu0twuph094ZEAQTkM494WgeENkPiR/TCrp5YREXp5YQ2dw2geYR4W0y4uWfphgRlMwm84S0S8S1amCgSjvIvMvE0CSEyRCw6hwmSlCnfPZ43EyWgUEXAH8NPPi2gNS9QSiO3W9DgVEaF1CoS1F9FuITFskE0JFvQIAA=== -->\n\n<!-- internal state end -->"},"request":{"retryCount":1,"signal":{}}},"response":{"url":"https://api.github.com/repos/GitMetricsLab/github_tracker/issues/comments/4555728713","status":401,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","connection":"close","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Wed, 27 May 2026 15:05:08 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","vary":"Accept-Encoding, Accept, X-Requested-With","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-media-type":"github.v3; format=json","x-github-request-id":"3C18:1E71:915BA81:23788CC7:6A170823","x-xss-protection":"0"},"data":{"message":"Requires authentication","documentation_url":"https://docs.github.com/rest","status":"401"}}}

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/config/passportConfig.js (1)

43-43: ⚡ Quick win

Prefer an allowlist projection here.

select('-password -__v') still forwards every other User field into req.user, so any future sensitive field becomes exposed by default. Select the exact fields handlers need instead of excluding just two known fields.

Suggested change
-        const user = await User.findById(id).select('-password -__v').lean();
+        const user = await User.findById(id)
+            .select('_id username email') // expand only with explicitly safe fields
+            .lean();
🤖 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/config/passportConfig.js` at line 43, The current deserialize logic
uses User.findById(id).select('-password -__v').lean(), which excludes only two
fields and risks leaking future sensitive fields; change this to an allowlist
projection on User.findById (e.g., explicitly select the exact fields your
handlers require such as '_id', 'email', 'name', roles, etc.) so req.user only
contains those properties—update the .select call in the same function where
const user is assigned (the User.findById(...) line) to list required fields
explicitly.
🤖 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/routes/auth.js`:
- Around line 46-51: The route currently returns raw error messages from the
auth/session store (err.message and destroyErr.message) to clients; change this
to log the full error server-side (use console.error or the app logger) inside
the error branches for the callback that handles logout and req.session.destroy,
and replace the JSON response bodies from res.status(500).json({ message: ...,
error: ... }) with a generic res.status(500).json({ message: 'Internal server
error' }) so no internal details are leaked from the logout handler or
req.session.destroy callback.

---

Nitpick comments:
In `@backend/config/passportConfig.js`:
- Line 43: The current deserialize logic uses
User.findById(id).select('-password -__v').lean(), which excludes only two
fields and risks leaking future sensitive fields; change this to an allowlist
projection on User.findById (e.g., explicitly select the exact fields your
handlers require such as '_id', 'email', 'name', roles, etc.) so req.user only
contains those properties—update the .select call in the same function where
const user is assigned (the User.findById(...) line) to list required fields
explicitly.
🪄 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

Run ID: a48941c4-0c0b-4d52-8984-51c5db4580ee

📥 Commits

Reviewing files that changed from the base of the PR and between 4ae0ef6 and 893e135.

📒 Files selected for processing (3)
  • backend/config/passportConfig.js
  • backend/routes/auth.js
  • backend/server.js

Comment thread backend/routes/auth.js
Comment on lines 46 to +51
if (err)
return res.status(500).json({ message: 'Logout failed', error: err.message });
else

req.session.destroy((destroyErr) => {
if (destroyErr) {
return res.status(500).json({ message: 'Session cleanup failed', error: destroyErr.message });
Copy link
Copy Markdown
Contributor

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

Don’t return raw auth/session errors to the client.

These responses expose internal Passport or session-store details on an auth endpoint. Return a generic 500 body here and log the underlying error server-side instead.

Suggested change
+const logger = require("../logger");
...
-            return res.status(500).json({ message: 'Logout failed', error: err.message });
+            logger.error('Logout failed', err);
+            return res.status(500).json({ message: 'Logout failed' });
...
-                return res.status(500).json({ message: 'Session cleanup failed', error: destroyErr.message });
+                logger.error('Session cleanup failed', destroyErr);
+                return res.status(500).json({ message: 'Session cleanup failed' });
📝 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
if (err)
return res.status(500).json({ message: 'Logout failed', error: err.message });
else
req.session.destroy((destroyErr) => {
if (destroyErr) {
return res.status(500).json({ message: 'Session cleanup failed', error: destroyErr.message });
const logger = require("../logger");
// ... rest of file imports ...
if (err) {
logger.error('Logout failed', err);
return res.status(500).json({ message: 'Logout failed' });
}
req.session.destroy((destroyErr) => {
if (destroyErr) {
logger.error('Session cleanup failed', destroyErr);
return res.status(500).json({ message: 'Session cleanup failed' });
🤖 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/routes/auth.js` around lines 46 - 51, The route currently returns raw
error messages from the auth/session store (err.message and destroyErr.message)
to clients; change this to log the full error server-side (use console.error or
the app logger) inside the error branches for the callback that handles logout
and req.session.destroy, and replace the JSON response bodies from
res.status(500).json({ message: ..., error: ... }) with a generic
res.status(500).json({ message: 'Internal server error' }) so no internal
details are leaked from the logout handler or req.session.destroy callback.

@anshul23102
Copy link
Copy Markdown
Contributor Author

Closing to split into separate PRs per issue, one for each of #554, #555, and #556.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant