You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
server.py: LOGGER.info leaks OAuth1 access token to logs at default log level #12
Python's default logging configuration emits INFO to stderr. Any operator running xmcp with log redirection (python server.py > xmcp.log 2>&1), inside a container with captured stderr, inside a process supervisor (systemd, launchd, supervisord), or inside a PaaS logging pipeline (Fly.io, Heroku, CloudWatch) will have the secret persisted to disk or forwarded to a log-aggregation service.
OAuth1 access tokens are long-lived credentials — X doesn't rotate them unless the user explicitly revokes or they go unused for extended periods. A token captured in logs is a real compromise.
Reproduction
# Fresh xmcp install with OAuth1 consumer credentials configured:
python server.py 2>&1| tee xmcp.log
# After auth completes, grep the log:
grep "OAuth1 access token:" xmcp.log
Returns the literal access token string.
Proposed fix
Options (in order of preference):
Remove the log line entirely. The token being set is already implied by the absence of any "no access token" error path.
Log only a token fingerprint.LOGGER.info("OAuth1 access token: %s... (len=%d)", access_token[:6], len(access_token)) — enough to distinguish between tokens in a multi-account deployment without leaking the secret.
Gate behind LOG_LEVEL=DEBUG. Safer than INFO but still fails when a debug-level log is inadvertently enabled or saved.
Option 1 is simplest and loses no useful diagnostic information.
Context
Discovered while building xmcp-companion, a Claude Code plugin that uses xdevplatform/xmcp for X API research workflows. We flag this to end users in our plugin's setup skill but would prefer to remove the flag once upstream fixes.
No private details are disclosed in this issue — the code is public, the behavior is reproducible from the public repo, and no actual token values are included.
Activity