Repository navigation
fix(configuration): refuse proxy and MCP URLs that parse as another host - #2389
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs real behavior proof before merge. What this changesThis PR rejects proxy, channel, MCP, plugin, and proxy-environment URLs whose HTTP scheme slashes cause the parser to read another host. Example: Save a Configuration with proxy.proxyUrl set to https:///v1.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness⛔ Blocked before merge - 3 items remain Keep this PR open: the URL validation change has owner support, but rejecting previously saved URLs also prevents compensation from restoring them after a failed update. Priority: P2 Before merge
Findings
Tests
Agent review detailsHow this fits togetherConfiguration and Preset admission pass native runtime settings through the selected Configuration Driver; validated documents enter filesystem or Kubernetes storage and later Agent deployment. flowchart TB
A[Configuration or Preset request] --> B[OCC admission]
B --> C[Configuration Driver]
C --> D[Shared URL validation]
D --> E[Configuration storage]
E --> F[Agent deployment]
Technical reviewBest possible solution: Keep the owner-approved admission rule while allowing trusted compensation to restore the exact previously stored document without relaxing validation of user writes. Do we have a high-confidence way to reproduce the issue? Current-main source accepts the reported literal proxy URLs, and the introduced validator rejects them; the compensation failure follows directly through OCC rollback and bundled-Driver validation, without executing target code. Is this the best way to solve the issue? Extending the existing shared validator is appropriately scoped and has feature-owner support, but write admission must remain compatible with restoration of an exact older snapshot. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 9ab1c06e6416. Provenance checked
TestingProof path: unit tests only. SecurityNone. EvidenceAcceptance criteria:
What I checked:
Likely related people:
LabelsLabel changes: No label changes. Label justifications:
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment HistoryReview history (3 earlier review cycles)
Reviewed October 14, 2026, 12:57 AM ET / 04:57 UTC (Revision 4). |
# Conflicts: # docs/guides/deploy/breaking-changes-archive.md # docs/guides/deploy/breaking-changes.md
|
Free's clanker here (an AI agent working on Free's behalf). Thanks. I reviewed head The one blocker is a conflict. #2385 just landed (9031ae3) and added its notice at the same spot in A note for whoever lands it: #2351 deliberately limited the slash rule to model
|
|
Free's clanker here (an AI agent working on Free's behalf). Thanks, Eric. I reviewed head The one blocker is a conflict again, sorry. #2388 just landed (8ccb33b) and its notice sits at the same spot in |
|
ClawSweeper status: review started. I am starting a fresh review of this pull request: fix(configuration): refuse proxy and MCP URLs that parse as another host This is item 1/1 in the current shard. Shard 0/1. This temporary status tracks the active review worker. The completed review will appear in the durable ClawSweeper review comment. Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted. |
|
Merged main through |
|
Free's clanker here (an AI agent working on Free's behalf). Landed as 67bd8d6, thanks Eric. Your main merge kept every main-side breaking-changes entry and the archive, and the code matches what we reviewed. |
Closes #2384
Problem
validateModelCredentialReferencesaccepts a proxy URLhttps:///v1,https:/v1, a channel proxyhttps:///slack, and an MCP server URLhttps:/mcp.https:///v1andhttps:/v1both parse ashttps://v1/(hostv1). ModelbaseUrlalready refuses an empty authority and a missing//. These other URL fields do not.Parent
c28bd23933b33fcb7a726afd8049d770321b0b31.Change
The shared URL check refuses an empty authority (
https:///v1, including a backslash in place of a slash) or a missing//(https:/v1,https:v1) on proxy, channel, MCP, plugin, and proxy-environment URLs. The message names the field and says to write an absolutehttp://orhttps://URL and save again. Fields whose last segment isbaseUrlare left to the model-provider check, which already has its own sentence. A Preset whose literal head is onlyhttp:,https:,http:/, orhttps:/, and still has an unfilled variable, is not a finished URL, so this check waits. The variable can supply//hostor/host.https:///{{ vars.path }}still fails, because the empty authority is already written. The new conformance file is registered on the baseline lane.Verification
Parent
c28bd23933b33fcb7a726afd8049d770321b0b31admittedhttps:///v1andhttps:/v1onproxy.proxyUrl, a channel proxy, an MCP server URL, andrequest.proxy.url.Head
fcd37fe350d1527708c98455cdcdd823dd36d6fc, which merges current main8e64d914692505239d627e9519b5c27e35e9d3e1:Exit 0. 1 passed, 0 failed. Those spellings throw
has an empty authority or a missing //, which parses as a different host.A proxy URL with a host does not throw.https:{{ vars.endpoint }}andhttps:/{{ vars.rest }}, with an unfilled variable after that literal head, do not throw.https:///{{ vars.path }}still throws. A modelbaseUrlofhttps:///v1is not claimed by this check.Exit 0. Status
passedon this head. No issues.tests/conformance/url-authority.test.mjsstays on the baseline lane.Exit 0.
docs/guides/deploy/breaking-changes.md2467,docs/guides/deploy/breaking-changes-archive.md1702.Risks
A Configuration or Preset that saved
https:///...orhttps:/...on a proxy, channel, MCP, or plugin URL is rejected on the next save until the URL names a host. A Preset that leaves the host in a variable afterhttps:orhttps:/is still accepted here and checked again once filled. ModelbaseUrlmessages are unchanged. The current page keeps the landed harness, observability, and OpenShell gateway notices.