Description
Docker push can fail when it attempts to reuse image layers from another repository through a cross-repository blob mount.
For example, when pushing an image from:
registry.example.com/1/networktest
to:
registry.example.com/2/networktest
Docker requests authorization for both the source and target repositories:
scope=repository:1/networktest:pull
scope=repository:2/networktest:pull,push
This produces a token request containing repeated scope query parameters:
GET /v2/token?service=ret2shell&scope=repository%3A1%2Fnetworktest%3Apull&scope=repository%3A2%2Fnetworktest%3Apull%2Cpush
Actual behavior
The token endpoint returns:
400 Bad Request
Failed to deserialize query string: scope: duplicate field `scope`
Docker then fails to authorize the cross-repository mount, resulting in errors similar to:
pushing with mount from 1/networktest
failed to authorize
A token request containing only one scope parameter works normally.
Expected behavior
The token endpoint should accept multiple scope parameters, authorize each requested repository scope, and include every authorized scope in the token's access entries.
Root cause
AuthRequest currently models the query parameter as a single optional string:
pub scope: Option<String>
The token handler extracts the query with Axum's default Query<AuthRequest>. When the query contains scope=A&scope=B, deserialization treats the second value as a duplicate struct field and rejects the request before the handler runs.
The token generation logic also processes at most one scope, so query parsing alone is not sufficient: every requested scope must also be authorized and added to the generated token.
Impact
This primarily affects Docker pushes that use cross-repository blob mounts. Docker cannot obtain a token containing both source pull and target pull,push permissions, preventing it from reusing existing layers and potentially causing the push to fail.
Description
Docker push can fail when it attempts to reuse image layers from another repository through a cross-repository blob mount.
For example, when pushing an image from:
to:
Docker requests authorization for both the source and target repositories:
This produces a token request containing repeated
scopequery parameters:Actual behavior
The token endpoint returns:
Docker then fails to authorize the cross-repository mount, resulting in errors similar to:
A token request containing only one
scopeparameter works normally.Expected behavior
The token endpoint should accept multiple
scopeparameters, authorize each requested repository scope, and include every authorized scope in the token'saccessentries.Root cause
AuthRequestcurrently models the query parameter as a single optional string:The token handler extracts the query with Axum's default
Query<AuthRequest>. When the query containsscope=A&scope=B, deserialization treats the second value as a duplicate struct field and rejects the request before the handler runs.The token generation logic also processes at most one scope, so query parsing alone is not sufficient: every requested scope must also be authorized and added to the generated token.
Impact
This primarily affects Docker pushes that use cross-repository blob mounts. Docker cannot obtain a token containing both source
pulland targetpull,pushpermissions, preventing it from reusing existing layers and potentially causing the push to fail.