fix(parser): preserve numeric credentials instead of dropping them (false NO_AUTH + missed WEAK_API_KEY)#50
Open
dmchaledev wants to merge 1 commit into
Open
fix(parser): preserve numeric credentials instead of dropping them (false NO_AUTH + missed WEAK_API_KEY)#50dmchaledev wants to merge 1 commit into
dmchaledev wants to merge 1 commit into
Conversation
An unquoted all-digit `auth.apiKey`/`auth.token` is parsed as a number (by JSON, and by YAML scalar coercion). `normalizeConfig` only accepted string credentials, so the value was silently dropped — yielding a false CRITICAL NO_AUTH on an authenticated config and skipping WEAK_API_KEY on a weak one. A long numeric string was additionally corrupted by lossy Number() coercion in the YAML path (e.g. a 32-digit key became 9.2e+31). - normalizeConfig: coerce numeric apiKey/token to their string form so NO_AUTH and WEAK_API_KEY evaluate them. - parseYamlScalar: only coerce to a number when it round-trips exactly, preserving long numeric and leading-zero values as strings. Genuine numeric fields (e.g. rateLimit.requestsPerMinute) are unaffected. Adds parser/scan regression tests covering strong and weak numeric credentials and JSON/YAML parity. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UkdL3AQvdFGEZDdzwbzpDj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
An MCP config whose
auth.apiKey/auth.tokenis written as an unquoted all-digit value is parsed as a number — byJSON.parse, and by the YAML scalar coercion inparseYamlScalar. ButnormalizeConfigonly acceptedtypeof === 'string'credentials, so the value was silently dropped. Consequences, both on the tool's headline CI-gate path:NO_AUTHand fails the gate.token/apiKeyslips pastWEAK_API_KEY.The YAML path was additionally corrupting long numeric credentials via lossy
Number()coercion — a 32-digit key92345678901234567890123456789012became9.2345678901234568e+31.Repro (built CLI at
main, before this change)The JSON twin (
"apiKey": "92345678901234567890123456789012") PASSES — same config, opposite verdict.Root cause
src/parser.tsparseYamlScalar:if (!isNaN(Number(value))) return Number(value);coerces any numeric-looking scalar to anumber, losing precision for long digit strings and leading zeros.src/parser.tsnormalizeConfig:if (typeof a['apiKey'] === 'string') …(and thetokensibling) reject a numeric credential, so it never reachesNO_AUTH/WEAK_API_KEY.Fix
normalizeConfig— coerce a numericapiKey/tokento its string form via a smallcoerceCredentialhelper, so both rules evaluate it. This also fixes JSON configs with an unquoted numeric credential, not just YAML.parseYamlScalar— only coerce a scalar to a number when it round-trips exactly (String(Number(v)) === v). Long numeric credentials/IDs (beyondNumber.MAX_SAFE_INTEGER), leading-zero values, and exponent/hex forms are preserved as strings instead of being mangled. Genuine numeric fields (rateLimit.requestsPerMinute: 60) round-trip and stay numbers.Both changes are localized to
src/parser.ts; no new dependencies, still zero-dependency indentation-driven YAML.Tests
Adds regression coverage in
src/__tests__/parser.test.ts:apiKey→ preserved exactly, noNO_AUTH, noWEAK_API_KEY;token→ flaggedWEAK_API_KEY;requestsPerMinutestill parses as a number; leading-zero scalars stay strings.Full suite:
typecheck+lintclean, 123 tests pass.Scope / relation to backlog
Distinct from the existing backlog. Issue #19 (already resolved in code) was about nested
transport.authmaps andtools:sequences being dropped entirely; this is a separate root cause — numeric scalar coercion — that survives that fix. No open issue or PR touches numeric-credential handling.Acceptance criteria
apiKey/tokendoes not emit a falseNO_AUTH.WEAK_API_KEY.rateLimit.requestsPerMinuteand other genuine numeric fields are unaffected.🤖 Generated with Claude Code
https://claude.ai/code/session_01UkdL3AQvdFGEZDdzwbzpDj
Generated by Claude Code