fix(R-1187 b): refuse a link whose parent path passes through a link; born keys listed; psql --set
gates / gates (push) Successful in 1m7s
gates / gates (push) Successful in 1m7s
Second automated security review finding, red-proved. The go-parity and docker -v gates that refused the push are green.
This commit is contained in:
@@ -1087,7 +1087,7 @@ func waitForDB(containerID, dbType string, env map[string]string) error {
|
||||
func psqlImportArgs(containerID, user, dbName string) []string {
|
||||
// R-1187 (g): stop on the first error — the dump is --clean --if-exists, so a failing statement is a real failure,
|
||||
// and without ON_ERROR_STOP psql went on and the import reported success over a half-loaded database.
|
||||
return []string{"exec", "-i", containerID, "psql", "-v", "ON_ERROR_STOP=1", "-U", user, "-d", dbName}
|
||||
return []string{"exec", "-i", containerID, "psql", "--set=ON_ERROR_STOP=1", "-U", user, "-d", dbName}
|
||||
}
|
||||
|
||||
// importDBDump imports a (possibly gzipped) SQL dump into the running database container.
|
||||
@@ -1203,6 +1203,26 @@ func extractTarGz(tgzPath, destDir string) error {
|
||||
}
|
||||
}
|
||||
|
||||
// parentThroughLink is true when any folder on name's path (inside the root) is a symbolic link.
|
||||
func parentThroughLink(rt *os.Root, name string) bool {
|
||||
dir := filepath.Dir(name)
|
||||
if dir == "." {
|
||||
return false
|
||||
}
|
||||
acc := ""
|
||||
for _, part := range strings.Split(dir, string(os.PathSeparator)) {
|
||||
acc = filepath.Join(acc, part)
|
||||
fi, err := rt.Lstat(acc)
|
||||
if err != nil {
|
||||
return false // not there yet: MkdirAll creates real folders
|
||||
}
|
||||
if fi.Mode()&os.ModeSymlink != 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// lchownFn is the owner seam (a test records it; production is os.Lchown).
|
||||
var lchownFn = func(r *os.Root, name string, uid, gid int) error { return r.Lchown(name, uid, gid) }
|
||||
|
||||
@@ -1270,6 +1290,13 @@ func extractTar(tarPath, destDir string) ([]string, error) {
|
||||
refused = append(refused, hdr.Name)
|
||||
continue
|
||||
}
|
||||
// The text check below is exact only when no folder on the link's path is itself a link (a „a" → „." makes
|
||||
// „a/b/l" really „b/l"): such an entry is refused (the security review's second case, pinned by
|
||||
// TestR1187b_NoLinkThroughALinkedParent).
|
||||
if parentThroughLink(rt, name) {
|
||||
refused = append(refused, hdr.Name)
|
||||
continue
|
||||
}
|
||||
resolved := filepath.Clean(filepath.Join(filepath.Dir(filepath.Join(root, name)), dst))
|
||||
if resolved != root && !strings.HasPrefix(resolved, root+string(os.PathSeparator)) {
|
||||
refused = append(refused, hdr.Name)
|
||||
|
||||
Reference in New Issue
Block a user