Skip to content

Fix Insecure Tenant Auth (ID Spoofing) - #2039

Merged
riteshbonthalakoti merged 2 commits into
riteshbonthalakoti:gssocfrom
ArshVermaGit:main_2
Jun 7, 2026
Merged

Fix Insecure Tenant Auth (ID Spoofing)#2039
riteshbonthalakoti merged 2 commits into
riteshbonthalakoti:gssocfrom
ArshVermaGit:main_2

Conversation

@ArshVermaGit

@ArshVermaGit ArshVermaGit commented Jun 6, 2026

Copy link
Copy Markdown

Description

This PR resolves a critical ID spoofing vulnerability in the /tickets/save endpoint by enforcing strict JWT validation on the backend.
Changes Made:

  • Updated the save_ticket FastAPI endpoint to accept the Request object.
  • Added logic to extract the Authorization Bearer token from the request headers.
  • Implemented supabase.auth.get_user(token) to cryptographically verify the JWT and retrieve the trusted user object.
  • Added a strict check: if a user_id is provided in the JSON body and it does not match the token's trusted user_id, the request is immediately rejected with a 403 Forbidden error and logged as a spoofing attempt.
  • Overrode the request_body.user_id with the trusted token ID to guarantee data integrity before insertion.
    By moving authentication to the backend token verification step, we guarantee that users can only ever submit tickets on behalf of their mathematically proven identity.

Resolved Issue

Resolves #2038

Summary by CodeRabbit

  • Bug Fixes

    • Added Bearer token authentication requirement for the ticket save endpoint
    • Implemented protection against user ID spoofing attempts
    • Enhanced security by enforcing token validation on API requests
  • Chores

    • Updated environment configuration for Supabase authentication

@vercel

vercel Bot commented Jun 6, 2026

Copy link
Copy Markdown

@ArshVermaGit is attempting to deploy a commit to the ritesh Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR hardens the /tickets/save endpoint against user ID spoofing by switching to Bearer token authentication. Supabase client initialization now uses the anon key to enforce row-level security, and the endpoint validates incoming tokens, derives the authenticated user ID from the token, and rejects any attempt to override it via the request payload.

Changes

Secure Ticket Creation

Layer / File(s) Summary
Supabase anon key configuration
backend/.env.example, backend/main.py
Environment example and Supabase client initialization updated to use SUPABASE_ANON_KEY instead of SUPABASE_SERVICE_KEY for RLS enforcement.
Bearer token auth and anti-spoofing protection
backend/main.py
The /tickets/save endpoint accepts the incoming Request, validates the Authorization: Bearer header via supabase.auth.get_user(), rejects mismatched payload user IDs with 403, and overwrites the user ID with the trusted token value.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

gssoc:approved, level:critical, type:security, quality:clean

Poem

🐰 A spoofing scheme thwarted with tokens so bright,
The anon key guards every write,
No more false user claims in the night,
Bearer tokens shine with RLS might,
Trust flows safe from payload blight! 🔐

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Fix Insecure Tenant Auth (ID Spoofing)' clearly and concisely summarizes the main security fix addressing JWT validation and user ID spoofing prevention.
Linked Issues check ✅ Passed The pull request fully implements all three acceptance criteria from issue #2038: extracts and validates Bearer tokens, derives user_id from verified tokens, and blocks spoofing attempts with HTTP 403.
Out of Scope Changes check ✅ Passed All changes are directly related to addressing the ID spoofing vulnerability: environment variable update for proper Supabase client initialization and endpoint modifications for JWT validation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ 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.

@ArshVermaGit ArshVermaGit left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Hi @ritesh-1918 ! The issue has been resolved. Please review the PR and merge it under GSSoC. Thanks!

@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.

🧹 Nitpick comments (2)
backend/main.py (2)

573-575: ⚡ Quick win

Preserve exception context with raise ... from e.

The static analysis tool correctly identifies that re-raising without exception chaining loses the original error context, making debugging harder. Using from e preserves the traceback.

♻️ Suggested fix
     except Exception as e:
         logger.error(f"Authentication failed: {e}")
-        raise HTTPException(status_code=401, detail="Authentication failed")
+        raise HTTPException(status_code=401, detail="Authentication failed") from e
🤖 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/main.py` around lines 573 - 575, The except block currently logs the
error via logger.error and then re-raises a new HTTPException, which drops the
original traceback; update the handler so the new exception is raised with
exception chaining (use raise HTTPException(status_code=401,
detail="Authentication failed") from e) to preserve the original context and
traceback for debugging; locate the except Exception as e block that calls
logger.error(f"Authentication failed: {e}") and modify the raise to include
"from e".

Source: Linters/SAST tools


578-580: ⚡ Quick win

Use hashed user IDs in spoofing attempt logs for consistency.

The rest of this file logs user IDs as SHA-256 hashes (e.g., lines 605, 614, 628), but this spoofing log exposes raw UUIDs. While UUIDs are not directly PII, maintaining consistent logging patterns improves privacy hygiene and reduces correlation risk in log aggregation.

♻️ Suggested fix
+    user_hash = hashlib.sha256(str(trusted_user_id).encode()).hexdigest()[:8]
+    attempted_hash = hashlib.sha256(str(request_body.user_id).encode()).hexdigest()[:8]
     if request_body.user_id and request_body.user_id != trusted_user_id:
-        logger.warning(f"ID Spoofing Attempt: Token user {trusted_user_id} tried to act as {request_body.user_id}")
+        logger.warning(f"ID Spoofing Attempt: Token user {user_hash} tried to act as {attempted_hash}")
         raise HTTPException(status_code=403, detail="User ID mismatch. Spoofing detected.")
🤖 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/main.py` around lines 578 - 580, The spoofing-warning currently logs
raw UUIDs; change the log to use a SHA-256 hash of both request_body.user_id and
trusted_user_id before emitting the message. Update the code around the if-check
that references request_body.user_id and trusted_user_id and replace the
logger.warning call to compute hex digests (e.g.,
hashlib.sha256(<id>.encode()).hexdigest()) for both IDs and include those hashed
values in the warning, leaving the HTTPException behavior unchanged.
🤖 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.

Nitpick comments:
In `@backend/main.py`:
- Around line 573-575: The except block currently logs the error via
logger.error and then re-raises a new HTTPException, which drops the original
traceback; update the handler so the new exception is raised with exception
chaining (use raise HTTPException(status_code=401, detail="Authentication
failed") from e) to preserve the original context and traceback for debugging;
locate the except Exception as e block that calls logger.error(f"Authentication
failed: {e}") and modify the raise to include "from e".
- Around line 578-580: The spoofing-warning currently logs raw UUIDs; change the
log to use a SHA-256 hash of both request_body.user_id and trusted_user_id
before emitting the message. Update the code around the if-check that references
request_body.user_id and trusted_user_id and replace the logger.warning call to
compute hex digests (e.g., hashlib.sha256(<id>.encode()).hexdigest()) for both
IDs and include those hashed values in the warning, leaving the HTTPException
behavior unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 65ab2c20-2dcb-431f-bf18-f51c3de4c677

📥 Commits

Reviewing files that changed from the base of the PR and between da8faf2 and fdb999f.

📒 Files selected for processing (2)
  • backend/.env.example
  • backend/main.py

@riteshbonthalakoti
riteshbonthalakoti changed the base branch from main to gssoc June 7, 2026 16:04
@riteshbonthalakoti

Copy link
Copy Markdown
Owner

Hi @ArshVermaGit! Thanks for the contribution. I have triaged your PR and set it to merge into the gssoc branch.

⚠️ MANDATORY GSSOC ONBOARDING STEPS:
Before your PR points are finalized on the leaderboard, you MUST complete these required steps:

  1. Star this repository: https://github.com/ritesh-1918/HELPDESK.AI (Mandatory)
  2. 👤 Follow the Project Admin: https://github.com/ritesh-1918 (Mandatory)
  3. 💼 Connect on LinkedIn: https://www.linkedin.com/in/ritesh1908/ (Mandatory)

Welcome to the HELPDESK.AI developer family! 🚀💻

@riteshbonthalakoti
riteshbonthalakoti merged commit fdb999f into riteshbonthalakoti:gssoc Jun 7, 2026
9 of 10 checks passed
@ArshVermaGit
ArshVermaGit deleted the main_2 branch June 7, 2026 16:16
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.

Insecure Tenant Auth (ID Spoofing)

2 participants