fix(claude): handle hex-encoded keychain credentials#48
Conversation
- Added a new function to parse credentials from hex-encoded JSON format, improving compatibility with macOS keychain items. - Updated the credential loading logic to utilize the new parsing function for both file and keychain sources. - Added a test case to verify the correct handling of hex-encoded JSON credentials.
Handle hex-encoded UTF-8 keychain credentials and parse them via
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3f5d017ef9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const text = ctx.host.fs.readText(CRED_FILE) | ||
| const parsed = JSON.parse(text) | ||
| const parsed = tryParseCredentialJSON(text) | ||
| if (!parsed) return null | ||
| const oauth = parsed.claudeAiOauth |
There was a problem hiding this comment.
Allow keychain fallback when file parse fails
If the credentials file exists but contains malformed JSON (e.g., partial write), tryParseCredentialJSON returns null and this code returns immediately, so the keychain fallback is never attempted. Before this change, a parse error in the file path would drop into the keychain branch, so users with a corrupt file but valid keychain entry now get a hard "Not logged in" error. Consider only returning null when a valid parsed file is present but missing tokens, and otherwise continue to keychain.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
There was a problem hiding this comment.
2 issues found across 2 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="plugins/claude/plugin.js">
<violation number="1" location="plugins/claude/plugin.js:28">
P3: The hex decoding uses `String.fromCharCode` per byte, which treats input as Latin-1 encoding rather than UTF-8. Multi-byte UTF-8 sequences (like 'é' = 0xC3 0xA9) would be incorrectly decoded as two Latin-1 characters. Consider using `TextDecoder` for proper UTF-8 decoding: `new TextDecoder().decode(new Uint8Array(hex.match(/.{2}/g).map(b => parseInt(b, 16))))`.</violation>
<violation number="2" location="plugins/claude/plugin.js:42">
P1: Early `return null` breaks the keychain fallback. If the credential file exists but can't be parsed, this now returns null immediately instead of falling through to try the keychain. Previously, `JSON.parse` would throw and the empty `catch` block would allow fallthrough to keychain.
Wrap the oauth check in a conditional instead to preserve fallback behavior:</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
- Added a new function to decode UTF-8 from hex-encoded byte arrays, enhancing the handling of non-ASCII characters in credentials. - Updated the credential loading logic to utilize the new decoding function for improved robustness. - Added tests to verify the correct decoding of hex-encoded JSON, including scenarios with corrupt files and non-ASCII characters.
Fixes credential loading when macOS keychain returns hex-encoded UTF-8 bytes instead of plain JSON.
TLDR: Some macOS keychain items are returned by
security ... -was hex-encoded strings (e.g.,7b0a...for{\n...). This PR adds support for decoding them.Changes
tryParseCredentialJSON()helper that attempts plain JSON parse first, then falls back to hex decodingMade with Cursor
Note
Low Risk
Low risk: changes are isolated to credential parsing in the Claude plugin, adding a safe fallback decoder plus tests; main risk is edge-case parsing behavior for unexpected keychain/file contents.
Overview
Fixes Claude credential loading when stored data isn’t plain JSON by adding
tryParseCredentialJSON()with a hex-to-UTF8 decode fallback (usingTextDecoderwhen available, otherwise a minimal UTF-8 decoder).loadCredentials()now uses this parser for both the credentials file and keychain paths, and tests cover file-corruption fallback to keychain plus hex-encoded (including non-ASCII) keychain values.Written by Cursor Bugbot for commit 159cffa. This will update automatically on new commits. Configure here.
Summary by cubic
Fixes credential parsing in the Claude plugin when macOS Keychain returns hex-encoded JSON, including non-ASCII, so OAuth tokens load reliably from both file and keychain. Prevents auth failures when
security ... -woutputs hex (e.g., "7b0a...").Written for commit 159cffa. Summary will update on new commits.