fix(cargo): harden README fetch, clarify status handling, strengthen tests#1330
Open
rdimitrov wants to merge 1 commit into
Open
fix(cargo): harden README fetch, clarify status handling, strengthen tests#1330rdimitrov wants to merge 1 commit into
rdimitrov wants to merge 1 commit into
Conversation
…tests Follow-up to #1207, addressing items from review of the cargo validator. Scoped to cargo + shared helpers only — no behavior change for existing npm/pypi/nuget/oci/mcpb publishers. SSRF hardening of the two-call README retrieval: - Pin the step-2 README URL to an allowed host (static.crates.io in prod; the base host under test) before fetching, so a metadata response cannot steer the validator at an internal/attacker host. - CheckRedirect policy pins every redirect hop to the same allowlist. - Cap the README body with io.LimitReader (5 MiB). Clearer status handling (previously any non-5xx/non-200 collapsed to "not found"): - 429 is reported as transient/retryable rather than "not found", at both steps. - A 403 from static.crates.io is disambiguated via the crate-version endpoint: genuinely-missing stays "not found"; exists-but-no-README gets an actionable "add a README with mcp-name and republish" message (mirrors NuGet). This continues the 5xx-vs-403 diagnostic split @P4ST4S started in the #1207 review. Add a shared, boundary-anchored containsMCPNameToken helper (prevents prefix confusion, e.g. a README declaring io.github.acme/widget-pro satisfying a claim for io.github.acme/widget) and use it from the cargo validator. Adopting it in the PyPI/NuGet validators is a follow-up (it is a behavior change for those already-live registries). Tests: hermetic positive ServerNameFormats; combined fixture gains a version-existence endpoint + cases for 403-missing vs 403-no-readme, 429, and prefix-confusion rejection; new foreign-README-host (SSRF) test; internal test for the helper. Docs: list crates.io in registry requirements + the Package doc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Follow-up to #1207, addressing items from the cargo validator review. Scoped to cargo + shared helpers — no behavior change for existing npm/pypi/nuget/oci/mcpb publishers. Safe to merge and promote.
Changes
SSRF hardening of the two-call README retrieval
static.crates.ioin prod; the base host under test) before fetching, so a metadata response can't steer the validator at an internal/attacker host.CheckRedirectpolicy pins every redirect hop to the same allowlist (the initial URL being pinned isn't enough if an upstream 3xx is followed).io.LimitReader(5 MiB).Clearer status handling (previously any non-5xx/non-200 collapsed to "not found")
mcp-nameand republish" message (mirrors the NuGet validator). This continues the 5xx-vs-403 diagnostic split @P4ST4S started in the feat: add cargo (crates.io) as a package registry type #1207 review — thanks!Shared
containsMCPNameTokenhelperBoundary-anchored ownership-token match (prevents prefix confusion, e.g. a README declaring
io.github.acme/widget-prosatisfying a claim forio.github.acme/widget), used here by the cargo validator only. Adopting it in PyPI/NuGet is a separate follow-up because it's a behavior change for those already-live registries.Tests & docs
Hermetic positive
ServerNameFormats; combined fixture gains a version-existence endpoint + cases for 403-missing vs 403-no-README, 429, and prefix-confusion rejection; new foreign-README-host (SSRF) test; internal test for the helper. Docs: listcrates.ioin the registry-requirements list + thePackagemodel doc.Testing
go build,go vet, full./internal/validators/...suite (incl. live cargo positive),make check-schema,validate-examplesall pass. No newgolangci-lintfindings.🤖 Generated with Claude Code