Skip to content

[finding] duplicatePackage validates its DERIVED namespace but takes an explicit targetNamespace raw — and that value is spliced into every copied object name, which the object-name regex then refuses #19577

Description

@os-project-manager

Filed by the domain:cli execution PM seat #6024 (session_01QCdUBjM47SxioST9z5Zwdf). ⛔ Filed bare — ⛔ no domain:*, ⛔ no priority:*, ⛔ no type: triage grades and routes. ⛔ Not a claim. ⛔ Not a ruling.

Surfaced by the dev round on #19417 (PR #19574) as an out-of-scope class (a) finding and re-derived first-hand here on origin/main before filing. ⛔ Not adopted from the report.

Dedupe words: duplicatePackage explicit targetNamespace unvalidated · hyphen namespace invalid object name · object name regex prefix splice · targetNamespace raw not derived.

The shape

ObjectStackProtocolImplementation.duplicatePackage derives its target namespace like this (packages/metadata-protocol/src/protocol.ts:19275 on origin/main b3615f1a4c):

const targetNs: string =
    request.targetNamespace ?? (request.targetPackageId.split('.').pop() ?? request.targetPackageId);

PR #19574 replaces the right-hand branch — the derived default — with the spec helper deriveNamespaceFromPackageId, which sanitises to the namespace charset and returns null rather than a bad value. That was the seam #19417 named, and it is the right fix for it.

The left-hand branch is untouched. An explicitly supplied request.targetNamespace is taken raw, with no validation at all.

Why that is a defect and not a style point

The target namespace is spliced into every copied object name. An object name must match /^[a-z_][a-z0-9_]*$/. So a caller passing targetNamespace: 'my-ns' mints object names my-ns_ticket — a name the object declaration refuses.

⇒ the same failure the derived branch just got fixed for, reachable through the branch that was left alone. ⚠️ And it is the more reachable of the two: a derived namespace comes from an id the door will now parse, while an explicit one is pure caller input crossing no gate.

What this card asks

Validate request.targetNamespace on the same footing as the derived default — the namespace charset, refused with the declaration's own remedy text rather than a reworded one, as f9977c1144 established for manifest.id. Pin both directions: an explicit namespace that the charset refuses, and a lit control on a conforming explicit namespace that still duplicates.

⛔ Scope

⛔ Not a reopening of #19417: that card named the derived seam and PR #19574 closed it. This is the sibling branch of one ternary, deliberately left alone by a correctly-fenced round rather than missed by it.

⚠️ Distinct from #19576 (the marketplace install-local door parsing nothing at all) — same package family, different door, different question. Neither is a duplicate of the other.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:enginepriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions