Skip to content

🔒 Fix JWT query parameter vulnerability via short-lived download tickets#99

Open
albatrosify wants to merge 1 commit into
developfrom
fix-jwt-query-parameter-vulnerability-2075765140352657835
Open

🔒 Fix JWT query parameter vulnerability via short-lived download tickets#99
albatrosify wants to merge 1 commit into
developfrom
fix-jwt-query-parameter-vulnerability-2075765140352657835

Conversation

@albatrosify
Copy link
Copy Markdown
Owner

🎯 What: Fixed a security vulnerability where the main JWT authentication token could be passed via the ?token= query parameter in the API.
⚠️ Risk: Query parameters are often logged in server access logs, browser history, and HTTP Referer headers. Exposing a long-lived authentication token in these places creates a risk of token theft and account compromise.
🛡️ Solution: Implemented a short-lived "download ticket" system.

  1. Added a GET /api/auth/ticket endpoint that generates a 5-minute JWT with a purpose: 'download' claim.
  2. Hardened the requireAuthOrQuery middleware to enforce that if a token is passed via the query string, it must possess this specific purpose: 'download' claim. The main authentication token is now rejected if passed in the query string.
  3. Updated the React frontend to fetch this short-lived ticket dynamically upon clicking the download button, rather than statically embedding the main auth token in href attributes.
  4. Added unit tests for the requireAuthOrQuery middleware to verify this new security boundary.

PR created automatically by Jules for task 2075765140352657835 started by @albatrosify

This patch eliminates a security vulnerability where the main, long-lived JWT authentication token was accepted via the `?token=` query parameter for browser-initiated downloads.

The fix introduces a `/api/auth/ticket` endpoint that generates short-lived (5 minute) tokens with a specific `purpose: 'download'` claim. The `requireAuthOrQuery` middleware has been updated to explicitly require this claim when a token is passed via the query string.

The frontend (`src/components/index.tsx`) has been updated to dynamically fetch this ticket and trigger the download programmatically, replacing the static `<a>` links that embedded the main auth token. Tests have been added to verify the middleware's enforcement of the new `purpose` claim.

Co-authored-by: albatrosify <64252708+albatrosify@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

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