fix(security): CWE-22 path traversal in copyFilesToContainer and deleteViaEphemeral
CWE-22 fix: - copyFilesToContainer: validate with filepath.Clean + IsAbs + strings.Contains(clean, '..'), use safeName for tar header - deleteViaEphemeral: call validateRelPath(filePath) before constructing rm command Fixes #1272
This commit is contained in:
parent
cde02594bc
commit
dc218212be
@ -73,9 +73,19 @@ func (h *TemplatesHandler) copyFilesToContainer(ctx context.Context, containerNa
|
|||||||
|
|
||||||
createdDirs := map[string]bool{}
|
createdDirs := map[string]bool{}
|
||||||
for name, content := range files {
|
for name, content := range files {
|
||||||
|
// CWE-22: reject absolute paths and path-traversal sequences
|
||||||
|
// before using the name in the tar header.
|
||||||
|
clean := filepath.Clean(name)
|
||||||
|
if filepath.IsAbs(clean) || strings.Contains(clean, "..") {
|
||||||
|
return fmt.Errorf("path traversal blocked: %s", name)
|
||||||
|
}
|
||||||
|
// Use the safe, cleaned name joined with destPath so the tar
|
||||||
|
// header Name is always a relative path inside destPath.
|
||||||
|
safeName := filepath.Join(destPath, clean)
|
||||||
|
|
||||||
// Create parent directories in tar (deduplicated)
|
// Create parent directories in tar (deduplicated)
|
||||||
dir := filepath.Dir(name)
|
dir := filepath.Dir(safeName)
|
||||||
if dir != "." && !createdDirs[dir] {
|
if dir != destPath && !createdDirs[dir] {
|
||||||
tw.WriteHeader(&tar.Header{
|
tw.WriteHeader(&tar.Header{
|
||||||
Typeflag: tar.TypeDir,
|
Typeflag: tar.TypeDir,
|
||||||
Name: dir + "/",
|
Name: dir + "/",
|
||||||
@ -86,7 +96,7 @@ func (h *TemplatesHandler) copyFilesToContainer(ctx context.Context, containerNa
|
|||||||
|
|
||||||
data := []byte(content)
|
data := []byte(content)
|
||||||
header := &tar.Header{
|
header := &tar.Header{
|
||||||
Name: name,
|
Name: safeName,
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
Size: int64(len(data)),
|
Size: int64(len(data)),
|
||||||
}
|
}
|
||||||
@ -143,6 +153,12 @@ func (h *TemplatesHandler) deleteViaEphemeral(ctx context.Context, volumeName, f
|
|||||||
return fmt.Errorf("docker not available")
|
return fmt.Errorf("docker not available")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CWE-22: validate filePath before constructing the rm command so
|
||||||
|
// a path-traversal sequence cannot escape /configs.
|
||||||
|
if err := validateRelPath(filePath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
resp, err := h.docker.ContainerCreate(ctx, &container.Config{
|
resp, err := h.docker.ContainerCreate(ctx, &container.Config{
|
||||||
Image: "alpine:latest",
|
Image: "alpine:latest",
|
||||||
Cmd: []string{"rm", "-rf", "/configs/" + filePath},
|
Cmd: []string{"rm", "-rf", "/configs/" + filePath},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user