Claude/init 1wgqn0 - #13
Merged
Merged
Conversation
Both local servers refuse a request whose Host is not this machine. That is
the guard against DNS rebinding: comparing Origin against Host does not
replace it, because a page served from evil.example pointed at 127.0.0.1
sends both headers reading evil.example and they match perfectly.
The name was matched with `name.startswith("127.")`. 127.evil.example starts
with those characters, is registrable, and can be pointed anywhere -- so the
test meant to recognise the 127/8 block admitted the exact attack the guard
exists to stop. Parse the address instead of comparing the string.
The same lines read a bracketed IPv6 Host wrongly: the brackets separate the
address from the port, so stripping the port first turned `[::1]` -- what a
client sends when the port is the default -- into ":", and a loopback caller
was refused.
Both faults were in both servers, because the MCP copy was a copy of the web
one. Whether a name is loopback now lives only in runtime/localhost.py, and
test_localhost.py fails if a module starts deciding it again. bind_is_loopback
is separated from host_is_local in the same move: 0.0.0.0 is a fine thing to
be addressed as and a bad thing to be bound to, and the two callers wanted
opposite answers from what had been one list.
The refusal is pinned over a real socket on both servers, with and without an
Origin header -- the Host check has to run before Origin is read, since a
non-browser client omits Origin and an Origin-only guard then has nothing to
say. Every guard here fails the suite when removed, including the IPv4-mapped
normalisation, which is asserted directly because the interpreters this runs
on already fold it and could not observe its absence.
The sibling plainsong-mcp carries its own copy and needs the same fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PBAjxy7cD6DzJ72NX8TJEc
1.3.0 blamed the missing GitHub Releases on skip-existing and shipped a fix for it. Reading the job logs rather than reasoning about them, all six release runs died at the same step with the same error: invalid-publisher, no Trusted Publisher configured on PyPI, environment MISSING. Every version up there had been uploaded by hand. skip-existing is still worth having -- it is what makes a re-run idempotent -- but it was never the blocker, and test and build passing in all six runs is what made the failure easy to keep mis-reading. docs/releasing.md is rewritten around that. It had been describing a project that "has never been published", sending the reader to the pending-publisher page -- which refuses a name that already exists rather than redirecting -- and telling them to publish the sibling "the same way" when the sibling has no release workflow at all. It now says which of PyPI's two pages applies when, that the claims printed in the error are exactly what the publisher must match, and that `environment: MISSING` means leave the field empty. It also records a consequence that is not obvious: a re-run uses the workflow file as it was at the tag. v1.0.1, v1.1.0 and v1.2.0 predate skip-existing, so those three cannot be backfilled by re-running -- they authenticate and then abort on files already on PyPI. From v1.3.0 on, a re-run completes. 1.4.0 rather than 1.3.1: plainsong.runtime.localhost is a new public module and a Host header that was accepted before is refused now. No notation changes -- 6,321 files compile to exactly the music they did in 1.0.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PBAjxy7cD6DzJ72NX8TJEc
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.
Description
[What changed and why. Link to the issue if one exists.]
Testing Done
[How you verified the change works — test output, manual steps, screenshots]
Reviewer notes: [Optional — anything you want the reviewer to know upfront]