mirror of https://github.com/docker/cli.git
context: Ensure import paths are valid
Signed-off-by: Chris Crone <christopher.crone@docker.com>
(cherry picked from commit 6f49197cab
)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
a22ed24b98
commit
a2f0cf527b
|
@ -7,7 +7,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
_ "crypto/sha256" // ensure ids can be computed
|
_ "crypto/sha256" // ensure ids can be computed
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -18,6 +17,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Store provides a context store for easily remembering endpoints configuration
|
// Store provides a context store for easily remembering endpoints configuration
|
||||||
|
@ -295,6 +295,19 @@ func Import(name string, s Writer, reader io.Reader) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isValidFilePath(p string) error {
|
||||||
|
if p != metaFile && !strings.HasPrefix(p, "tls/") {
|
||||||
|
return errors.New("unexpected context file")
|
||||||
|
}
|
||||||
|
if path.Clean(p) != p {
|
||||||
|
return errors.New("unexpected path format")
|
||||||
|
}
|
||||||
|
if strings.Contains(p, `\`) {
|
||||||
|
return errors.New(`unexpected '\' in path`)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func importTar(name string, s Writer, reader io.Reader) error {
|
func importTar(name string, s Writer, reader io.Reader) error {
|
||||||
tr := tar.NewReader(&LimitedReader{R: reader, N: maxAllowedFileSizeToImport})
|
tr := tar.NewReader(&LimitedReader{R: reader, N: maxAllowedFileSizeToImport})
|
||||||
tlsData := ContextTLSData{
|
tlsData := ContextTLSData{
|
||||||
|
@ -309,10 +322,13 @@ func importTar(name string, s Writer, reader io.Reader) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if hdr.Typeflag == tar.TypeDir {
|
if hdr.Typeflag != tar.TypeReg {
|
||||||
// skip this entry, only taking files into account
|
// skip this entry, only taking files into account
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if err := isValidFilePath(hdr.Name); err != nil {
|
||||||
|
return errors.Wrap(err, hdr.Name)
|
||||||
|
}
|
||||||
if hdr.Name == metaFile {
|
if hdr.Name == metaFile {
|
||||||
data, err := ioutil.ReadAll(tr)
|
data, err := ioutil.ReadAll(tr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -358,10 +374,13 @@ func importZip(name string, s Writer, reader io.Reader) error {
|
||||||
var importedMetaFile bool
|
var importedMetaFile bool
|
||||||
for _, zf := range zr.File {
|
for _, zf := range zr.File {
|
||||||
fi := zf.FileInfo()
|
fi := zf.FileInfo()
|
||||||
if fi.IsDir() {
|
if !fi.Mode().IsRegular() {
|
||||||
// skip this entry, only taking files into account
|
// skip this entry, only taking regular files into account
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if err := isValidFilePath(zf.Name); err != nil {
|
||||||
|
return errors.Wrap(err, zf.Name)
|
||||||
|
}
|
||||||
if zf.Name == metaFile {
|
if zf.Name == metaFile {
|
||||||
f, err := zf.Open()
|
f, err := zf.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -175,7 +175,7 @@ func TestImportTarInvalid(t *testing.T) {
|
||||||
var r io.Reader = source
|
var r io.Reader = source
|
||||||
s := New(testDir, testCfg)
|
s := New(testDir, testCfg)
|
||||||
err = Import("tarInvalid", s, r)
|
err = Import("tarInvalid", s, r)
|
||||||
assert.ErrorContains(t, err, "invalid context: no metadata found")
|
assert.ErrorContains(t, err, "unexpected context file")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImportZip(t *testing.T) {
|
func TestImportZip(t *testing.T) {
|
||||||
|
@ -254,5 +254,5 @@ func TestImportZipInvalid(t *testing.T) {
|
||||||
var r io.Reader = source
|
var r io.Reader = source
|
||||||
s := New(testDir, testCfg)
|
s := New(testDir, testCfg)
|
||||||
err = Import("zipInvalid", s, r)
|
err = Import("zipInvalid", s, r)
|
||||||
assert.ErrorContains(t, err, "invalid context: no metadata found")
|
assert.ErrorContains(t, err, "unexpected context file")
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,3 +29,19 @@ func TestConfigModification(t *testing.T) {
|
||||||
assert.Equal(t, &testEP2{}, cfgCopy.endpointTypes["ep1"]())
|
assert.Equal(t, &testEP2{}, cfgCopy.endpointTypes["ep1"]())
|
||||||
assert.Equal(t, &testEP3{}, cfgCopy.endpointTypes["ep2"]())
|
assert.Equal(t, &testEP3{}, cfgCopy.endpointTypes["ep2"]())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidFilePaths(t *testing.T) {
|
||||||
|
paths := map[string]bool{
|
||||||
|
"tls/_/../../something": false,
|
||||||
|
"tls/../../something": false,
|
||||||
|
"../../something": false,
|
||||||
|
"/tls/absolute/unix/path": false,
|
||||||
|
`C:\tls\absolute\windows\path`: false,
|
||||||
|
"C:/tls/absolute/windows/path": false,
|
||||||
|
"tls/kubernetes/key.pem": true,
|
||||||
|
}
|
||||||
|
for p, expectedValid := range paths {
|
||||||
|
err := isValidFilePath(p)
|
||||||
|
assert.Equal(t, err == nil, expectedValid, "%q should report valid as: %v", p, expectedValid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue