Be more restrictive when copying secrets into Docker builds
Collapse the Kubernetes directories by copying files directly, skipping
'..' directories, and avoid the use of '.../.'
@@ -202,15 +202,50 @@ func (d *DockerBuilder) copySecrets(secrets []api.SecretBuildSource, buildDir st
if err := os.MkdirAll(dstDir, 0777); err != nil {
return err
}
+ glog.V(3).Infof("Copying files from the build secret %q to %q", s.Secret.Name, dstDir)
+
+ // Secrets contain nested directories and fairly baroque links. To prevent extra data being
+ // copied, perform the following steps:
+ //
+ // 1. Only top level files and directories within the secret directory are candidates
+ // 2. Any item starting with '..' is ignored
+ // 3. Destination directories are created first with 0777
+ // 4. Use the '-L' option to cp to copy only contents.
+ //
srcDir := filepath.Join(strategy.SecretBuildSourceBaseMountPath, s.Secret.Name)
- glog.V(3).Infof("Copying files from the build secret %q to %q", s.Secret.Name, filepath.Clean(s.DestinationDir))
- out, err := exec.Command("cp", "-vrf", srcDir+"/.", dstDir+"/").Output()
+ if err := filepath.Walk(srcDir, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+ if srcDir == path {
+ return nil
+ }
+
+ // skip any contents that begin with ".."
+ if strings.HasPrefix(filepath.Base(path), "..") {
+ if info.IsDir() {
+ return filepath.SkipDir
+ }
+ return nil
+ }
+
+ // ensure all directories are traversable
+ if info.IsDir() {
+ if err := os.MkdirAll(dstDir, 0777); err != nil {
+ return err
+ }
+ }
+ out, err := exec.Command("cp", "-vLRf", path, dstDir+"/").Output()
if err != nil {
glog.V(4).Infof("Secret %q failed to copy: %q", s.Secret.Name, string(out))
return err
}
- // See what is copied where when debugging.
- glog.V(5).Infof(string(out))
+ // See what is copied when debugging.
+ glog.V(5).Infof("Result of secret copy %s\n%s", s.Secret.Name, string(out))
+ return nil
+ }); err != nil {
+ return err
+ }
}
return nil
}
