Skip to content
This repository has been archived by the owner on Aug 14, 2020. It is now read-only.

Additional validation on malformed images #204

Merged
merged 5 commits into from
Oct 14, 2016

Conversation

lucab
Copy link
Contributor

@lucab lucab commented Oct 10, 2016

This PR introduces some additional validation before converting Docker images. This addresses:

  • an infinite loop when converting images with a cyclic dependency chain (CVE-2016-8579)
  • a path traversal when extracting layers with crafted IDs (CVE-2016-7569)

It also introduces fixtures and tests script for such cases.

Fixes #201
Fixes #203

Copy link
Contributor

@jonboulle jonboulle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!


curImgID := imgID

var err error
for curImgID != "" {
if _, ok := deps[curImgID]; ok {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, since you're using a bool you can just use the default value check (if deps[curImgID])

@lucab
Copy link
Contributor Author

lucab commented Oct 13, 2016

@jonboulle rebased to address the nit and to include the reference to the second CVE.

/cc @thebeeman

@@ -60,3 +63,21 @@ func ParseDockerURL(arg string) (*ParsedDockerURL, error) {
p, err := docker.ParseDockerURL(arg)
return (*ParsedDockerURL)(p), err
}

// IsValidLayerRefs validates a layer refs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused - remove this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was supposed to be a library-exposed helper, but I guess we may re-introduce it later as soon as any consumers need it.

@@ -279,14 +282,24 @@ func extractEmbeddedLayer(file *os.File, layerID string, outputPath string) (*os
return layerFile, nil
}

// getAncestry computes an image ancestry, returning an ordered list
// of dependencies starting from the topmost image to the base.
// It checks for dependency loops via duplicates detection in the image
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicate detection

ancestry = append(ancestry, curImgID)
log.Debug(`Getting ancestry for layer "`, curImgID, `".`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO nicer to just format the string here: fmt.Sprintf("... %q ...", curImgID)

return nil
}

// IsValidLayerId validates a layer ID
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming nit: generally IsFoo functions return a bool. Instead perhaps AssertValidLayerId or ValidateLayerID

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, this was just returning a bool at first but then changed to error returning, but I forgot to reflect that in the naming.

This commit fixes a possible infinite loop while traversing
the dependency ancestry of a malformed local image file.

This has been assigned CVE-2016-8579:
appc#203 (comment)
@lucab
Copy link
Contributor Author

lucab commented Oct 13, 2016

Further iteration on this: removed unused bits, renamed function and cleaned the debug printing.


// ValidateLayerId validates a layer ID
func ValidateLayerId(id string) error {
validId := regexp.MustCompile(`^(\w+:)?([A-Fa-f0-9]+)$`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, missed this on previous pass: this should a global variable (so failure would be at initialization time, not function invocation time)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack, moved to a global var stanza.

This commit introduces validation of layer IDs while handling images,
in order to avoid path traversal when unpacking layer content.
This is typically mitigated for remote usecases by registry conformance,
but can still be exploited locally.

This has been assigned CVE-2016-7569:
http://www.openwall.com/lists/oss-security/2016/09/28/8
Copy link
Contributor

@jonboulle jonboulle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jonboulle jonboulle merged commit 2ab8826 into appc:master Oct 14, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Infinite loop vulnerability in retrieving images chain Path traversals present in image converting
2 participants