xmlitemwrap

command
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 14, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Command xmlitemwrap finds a specific, mechanically-detectable AWS query/XML wire-shape bug: a plain string list emitted with structure wrapped around each element instead of the real flat <someSet><item>value</item></someSet> shape.

gopherstack-6flj's hand sweep of ec2 (the largest query/XML service in this repo) found this same mistake five separate times (commits 3337c961d, b430921d9): a Go field declared as a slice of a struct whose only real member is itself tagged `xml:"item"` or `xml:"item,omitempty"`, rather than a slice of the scalar the SDK actually deserializes. ec2 is EC2-Query (`awsEc2query_`), which names its repeated list element "item"; the classic AWS Query protocol (`awsAwsquery_`, 14 more services per services/_PROTOCOLS.md -- rds, sns, iam, autoscaling, cloudformation, ...) names the same repeated element "member" instead (confirmed against sns@v1.42.4 and rds@v1.124.1's deserializers.go, both switching on strings.EqualFold("member", t.Name.Local)) -- this tool treats "item" and "member" as equally valid sentinel names, since the same mistake is equally possible under either convention. Two concrete shapes recur:

  • DOUBLE-WRAP: the slice field's own tag is a sentinel name (or "...>"+sentinel) and its element struct's single member is ALSO tagged with a sentinel name -- `<item><item>value</item></item>` on the wire. This decodes to a real aws-sdk-go-v2 client as "deserialization failed ... expected value for item element, got xml.StartElement" -- a hard failure, not a silent drop.
  • NAMED-CHILD: the slice field's own tag is a sentinel name but its element struct's single member is tagged with some OTHER name -- `<item><instanceId>i-123</instanceId></item>` instead of plain `<item>i-123</item>`. Same hard decode failure.

Both shapes are structurally identical to "declare the wrapper one level too deep." A list-of-object shape where the element struct has more than one real member is a different, often genuinely correct, AWS shape (e.g. TagSet's Key/Value pairs) and is never flagged.

CONFIDENCE. A double-wrap hit is always reported CONFIDENT: item-in-item is never a real AWS shape -- no query/XML deserializer in this repo's pinned SDKs ever nests a literal <item> under <item>.

A named-child hit is ALWAYS reported NEEDS REVIEW, never confident. A "Set"/"List"-suffixed wrapper name was tried as a confidence signal and rejected after checking this tool's own repo-wide named-child findings against ec2@v1.319.1/deserializers.go by hand: it fires identically on a real confirmed bug (RunScheduledInstances' InstanceIDSet, commit 3337c961d, single member "instanceId") and on a genuinely correct AWS shape with the exact same structure (GetInstanceTypesFromInstanceRequirements' InstanceTypeSet, whose real element type types.InstanceTypeInfoFromInstanceRequirements has exactly one member, InstanceType). ec2 turns out to declare many real single- and under-implemented multi-member object-list types this way (types.AttributeValue, types.IpamOperatingRegion, types.PoolCidrBlock, types.UnsuccessfulItem, types.CapacityReservationGroup, types.SnapshotRecycleBinInfo, ...) -- none of which decode-crash a real client, unlike the confirmed bugs. There is no purely-syntactic signal that separates them; only reading the pinned SDK's own deserializer for that element type does. DescribeVpcEndpointServicePermissions's AllowedPrincipals is the same story: single member tagged "principal", not "item", but a genuinely correct partial rendering of the real two-member types.AllowedPrincipal (Principal + PrincipalType).

This is an AST-based structural scan (go/parser + go/ast + reflect struct-tag parsing), not a regex: gopherstack-4xr5 is a regex bug of exactly this kind, missed by a prior auditor that tried to read struct tags with a pattern instead of the parser.

Usage:

go run ./cmd/xmlitemwrap                   # report to stdout
go run ./cmd/xmlitemwrap -json out.json     # also write full finding list as JSON

Exit codes: 0 no confident findings (needs-review hits may still be printed), 1 a run error (can't resolve the repo root, can't parse a file), 2 at least one confident finding -- gates CI once trusted.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL