RocketChat / RocketChat/EmbeddedChat
Bug: OAuth callback crashes on malformed `state` due to unhandled `decodeURIComponent` error
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 165
- Forks
- 381
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 1
Description
Description
The OAuth callback endpoint decodes the state query parameter without guarding against invalid percent-encoding, which can throw a URIError and break the entire callback flow.
Code reference: CallbackEndpoint.ts:44
At that line, decodeURIComponent(state) is called directly inside Promise.all. If state contains malformed encoding (e.g., a trailing % or an invalid UTF-8 sequence), decodeURIComponent throws a URIError and the endpoint fails before building a safe callback response.
Steps to Reproduce
- Trigger the callback endpoint with a malformed
statevalue:
/api/apps/public/{appId}/callback?code=valid_code&state=%E0%A4%A - Observe server logs and response.
- The request fails before token exchange handling completes.
Expected Behavior
The endpoint should handle malformed state safely and return a controlled callback response (e.g., 400 with a user-friendly error page), not crash/fail via an unhandled decode error.
Actual Behavior
Malformed state causes decodeURIComponent to throw, which interrupts request handling and breaks the OAuth callback flow.
Impact
- Login flow can fail unexpectedly for users.
- Crafted callback URLs can cause repeated endpoint failures.
Suggested Fix Direction
- Wrap
statedecoding in atry/catchblock:
let decodedState: string;
try {
decodedState = decodeURIComponent(state);
} catch (e) {
return context.sendJson({ error: 'Invalid state parameter' }, 400);
}
- Validate
origin/statebefore use. - Return a controlled error response when
stateis invalid.
Note: This issue was identified while reviewing the OAuth callback implementation. A fix would improve robustness against both accidental and crafted malformed callback URLs.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at CallbackEndpoint.ts:44, where the OAuth callback decodes the state parameter inside Promise.all. Reproduce the endpoint request with the malformed state value from the issue and trace the response path. Done means malformed state no longer causes an unhandled URIError and returns a controlled 400 callback response.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, authentication
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100