Skip to content

fix(security): PKCE verifier leak, OAuth refresh Content-Type, tool_choice mcp_ prefix#1757

Closed
0xbyt4 wants to merge 1 commit into
NousResearch:mainfrom
0xbyt4:fix/anthropic-adapter-security
Closed

fix(security): PKCE verifier leak, OAuth refresh Content-Type, tool_choice mcp_ prefix#1757
0xbyt4 wants to merge 1 commit into
NousResearch:mainfrom
0xbyt4:fix/anthropic-adapter-security

Conversation

@0xbyt4

@0xbyt4 0xbyt4 commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Three bugs in agent/anthropic_adapter.py found during security audit:

  1. PKCE code_verifier leaked via OAuth state parameterrun_hermes_oauth_login() set "state": verifier, exposing the PKCE secret in the authorization URL (browser history, proxy logs, Referer headers). Now uses a separate secrets.token_urlsafe(16) value.

  2. refresh_hermes_oauth_token used wrong Content-Type — sent application/json but RFC 6749 requires application/x-www-form-urlencoded for token endpoints. The other refresh function (_refresh_oauth_token) already used the correct format.

  3. tool_choice name not mcp_-prefixed for OAuth — when is_oauth=True, all tool names get mcp_ prefix but tool_choice did not, causing Anthropic API rejection (name mismatch between tools array and tool_choice).

Test plan

  • TestPKCESecurityBugs::test_auth_url_does_not_contain_verifier — verifies verifier not in URL
  • TestRefreshContentType::test_hermes_refresh_uses_form_urlencoded — verifies correct Content-Type
  • TestToolChoiceOAuthPrefix::test_specific_tool_choice_gets_mcp_prefix_with_oauth — verifies mcp_ prefix on tool_choice
  • 77 existing tests pass, 0 regressions

…hoice prefix

1. PKCE code_verifier was used as OAuth state parameter, leaking the
   PKCE secret in the authorization URL (browser history, proxy logs,
   Referer headers). Now uses a separate random value for state.

2. refresh_hermes_oauth_token sent application/json but RFC 6749
   requires application/x-www-form-urlencoded for token endpoints.
   Matched to _refresh_oauth_token which already used the correct format.

3. When is_oauth=True, tool names get mcp_ prefix but tool_choice
   name did not, causing Anthropic API rejection (name mismatch).
   Now prefixes tool_choice name to match tool definitions.
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #1775. Cherry-picked your commit onto current main with authorship preserved. All three fixes (PKCE state leak, refresh Content-Type, tool_choice prefix) are in. Thanks @0xbyt4!

@teknium1 teknium1 closed this Mar 17, 2026
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.

2 participants