Merge pull request #314 from stevvooe/lockdown-uuid-route

registry/api/v2: stronger validation for uuid field in urls
This commit is contained in:
Stephen Day 2015-04-02 13:57:17 -07:00
commit 7c3b73482f
3 changed files with 22 additions and 6 deletions

View file

@ -2035,7 +2035,7 @@ The following parameters should be specified on the request:
|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| |`Host`|header|Standard HTTP Host Header. Should be set to the registry host.|
|`Authorization`|header|An RFC7235 compliant authorization header.| |`Authorization`|header|An RFC7235 compliant authorization header.|
|`name`|path|Name of the target repository.| |`name`|path|Name of the target repository.|
|`uuid`|path|A uuid identifying the upload. This field can accept almost anything.| |`uuid`|path|A uuid identifying the upload. This field can accept characters that match `[a-zA-Z0-9-_.=]+`.|
@ -2193,7 +2193,7 @@ The following parameters should be specified on the request:
|`Content-Range`|header|Range of bytes identifying the desired block of content represented by the body. Start must the end offset retrieved via status check plus one. Note that this is a non-standard use of the `Content-Range` header.| |`Content-Range`|header|Range of bytes identifying the desired block of content represented by the body. Start must the end offset retrieved via status check plus one. Note that this is a non-standard use of the `Content-Range` header.|
|`Content-Length`|header|Length of the chunk being uploaded, corresponding the length of the request body.| |`Content-Length`|header|Length of the chunk being uploaded, corresponding the length of the request body.|
|`name`|path|Name of the target repository.| |`name`|path|Name of the target repository.|
|`uuid`|path|A uuid identifying the upload. This field can accept almost anything.| |`uuid`|path|A uuid identifying the upload. This field can accept characters that match `[a-zA-Z0-9-_.=]+`.|
@ -2363,7 +2363,7 @@ The following parameters should be specified on the request:
|`Content-Range`|header|Range of bytes identifying the block of content represented by the body. Start must the end offset retrieved via status check plus one. Note that this is a non-standard use of the `Content-Range` header. May be omitted if no data is provided.| |`Content-Range`|header|Range of bytes identifying the block of content represented by the body. Start must the end offset retrieved via status check plus one. Note that this is a non-standard use of the `Content-Range` header. May be omitted if no data is provided.|
|`Content-Length`|header|Length of the chunk being uploaded, corresponding to the length of the request body. May be zero if no data is provided.| |`Content-Length`|header|Length of the chunk being uploaded, corresponding to the length of the request body. May be zero if no data is provided.|
|`name`|path|Name of the target repository.| |`name`|path|Name of the target repository.|
|`uuid`|path|A uuid identifying the upload. This field can accept almost anything.| |`uuid`|path|A uuid identifying the upload. This field can accept characters that match `[a-zA-Z0-9-_.=]+`.|
|`digest`|query|Digest of uploaded blob.| |`digest`|query|Digest of uploaded blob.|
@ -2538,7 +2538,7 @@ The following parameters should be specified on the request:
|`Authorization`|header|An RFC7235 compliant authorization header.| |`Authorization`|header|An RFC7235 compliant authorization header.|
|`Content-Length`|header|The `Content-Length` header must be zero and the body must be empty.| |`Content-Length`|header|The `Content-Length` header must be zero and the body must be empty.|
|`name`|path|Name of the target repository.| |`name`|path|Name of the target repository.|
|`uuid`|path|A uuid identifying the upload. This field can accept almost anything.| |`uuid`|path|A uuid identifying the upload. This field can accept characters that match `[a-zA-Z0-9-_.=]+`.|

View file

@ -28,7 +28,7 @@ var (
Name: "uuid", Name: "uuid",
Type: "opaque", Type: "opaque",
Required: true, Required: true,
Description: `A uuid identifying the upload. This field can accept almost anything.`, Description: "A uuid identifying the upload. This field can accept characters that match `[a-zA-Z0-9-_.=]+`.",
} }
digestPathParameter = ParameterDescriptor{ digestPathParameter = ParameterDescriptor{
@ -985,7 +985,7 @@ var routeDescriptors = []RouteDescriptor{
{ {
Name: RouteNameBlobUploadChunk, Name: RouteNameBlobUploadChunk,
Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/blobs/uploads/{uuid}", Path: "/v2/{name:" + RepositoryNameRegexp.String() + "}/blobs/uploads/{uuid:[a-zA-Z0-9-_.=]+}",
Entity: "Blob Upload", Entity: "Blob Upload",
Description: "Interact with blob uploads. Clients should never assemble URLs for this endpoint and should only take it through the `Location` header on related API requests. The `Location` header and its parameters should be preserved by clients, using the latest value returned via upload related API calls.", Description: "Interact with blob uploads. Clients should never assemble URLs for this endpoint and should only take it through the `Location` header on related API requests. The `Location` header and its parameters should be preserved by clients, using the latest value returned via upload related API calls.",
Methods: []MethodDescriptor{ Methods: []MethodDescriptor{

View file

@ -98,6 +98,7 @@ func TestRouter(t *testing.T) {
}, },
}, },
{ {
// support uuid proper
RouteName: RouteNameBlobUploadChunk, RouteName: RouteNameBlobUploadChunk,
RequestURI: "/v2/foo/bar/blobs/uploads/D95306FA-FAD3-4E36-8D41-CF1C93EF8286", RequestURI: "/v2/foo/bar/blobs/uploads/D95306FA-FAD3-4E36-8D41-CF1C93EF8286",
Vars: map[string]string{ Vars: map[string]string{
@ -113,6 +114,21 @@ func TestRouter(t *testing.T) {
"uuid": "RDk1MzA2RkEtRkFEMy00RTM2LThENDEtQ0YxQzkzRUY4Mjg2IA==", "uuid": "RDk1MzA2RkEtRkFEMy00RTM2LThENDEtQ0YxQzkzRUY4Mjg2IA==",
}, },
}, },
{
// supports urlsafe base64
RouteName: RouteNameBlobUploadChunk,
RequestURI: "/v2/foo/bar/blobs/uploads/RDk1MzA2RkEtRkFEMy00RTM2LThENDEtQ0YxQzkzRUY4Mjg2IA_-==",
Vars: map[string]string{
"name": "foo/bar",
"uuid": "RDk1MzA2RkEtRkFEMy00RTM2LThENDEtQ0YxQzkzRUY4Mjg2IA_-==",
},
},
{
// does not match
RouteName: RouteNameBlobUploadChunk,
RequestURI: "/v2/foo/bar/blobs/uploads/totalandcompletejunk++$$-==",
StatusCode: http.StatusNotFound,
},
{ {
// Check ambiguity: ensure we can distinguish between tags for // Check ambiguity: ensure we can distinguish between tags for
// "foo/bar/image/image" and image for "foo/bar/image" with tag // "foo/bar/image/image" and image for "foo/bar/image" with tag