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:
@@ -186,7 +186,7 @@ func TestR1187g_PostgisIsPostgresAndPsqlStopsOnError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
args := strings.Join(psqlImportArgs("c", "u", "d"), " ")
|
||||
if !strings.Contains(args, "-v ON_ERROR_STOP=1") {
|
||||
if !strings.Contains(args, "--set=ON_ERROR_STOP=1") {
|
||||
t.Fatalf("psql does not stop on error: %s", args)
|
||||
}
|
||||
}
|
||||
@@ -216,3 +216,35 @@ func TestR1187b_NoWriteThroughALinkThatLeavesTheFolder(t *testing.T) {
|
||||
t.Fatal("a file was written OUTSIDE the app's folder through a pre-existing link")
|
||||
}
|
||||
}
|
||||
|
||||
// (b), the security review's second case — a parser differential: link „a" → „." makes „a/b" really „b", so a later
|
||||
// link „a/b/l" → „../.." passes a path-TEXT check (root/a/b/../.. = root) while it really points one level ABOVE the
|
||||
// app's folder. A link entry whose parent path passes through a link is refused and listed. RED-PROOF: with the text
|
||||
// check only, „a/b/l" is created and points outside.
|
||||
func TestR1187b_NoLinkThroughALinkedParent(t *testing.T) {
|
||||
dest := t.TempDir()
|
||||
tarPath := filepath.Join(t.TempDir(), "d.tar")
|
||||
f, _ := os.Create(tarPath)
|
||||
tw := tar.NewWriter(f)
|
||||
tw.WriteHeader(&tar.Header{Name: "a", Typeflag: tar.TypeSymlink, Linkname: "."})
|
||||
tw.WriteHeader(&tar.Header{Name: "a/b/", Typeflag: tar.TypeDir, Mode: 0o755})
|
||||
tw.WriteHeader(&tar.Header{Name: "a/b/l", Typeflag: tar.TypeSymlink, Linkname: "../.."})
|
||||
tw.Close()
|
||||
f.Close()
|
||||
old := lchownFn
|
||||
lchownFn = func(*os.Root, string, int, int) error { return nil }
|
||||
defer func() { lchownFn = old }()
|
||||
refused, err := extractTar(tarPath, dest)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, p := range []string{filepath.Join(dest, "b", "l"), filepath.Join(dest, "a", "b", "l")} {
|
||||
if _, err := os.Lstat(p); err == nil {
|
||||
real, _ := filepath.EvalSymlinks(p)
|
||||
t.Fatalf("a link through a linked parent was created (%s → %s)", p, real)
|
||||
}
|
||||
}
|
||||
if !strings.Contains(strings.Join(refused, ","), "a/b/l") {
|
||||
t.Fatalf("the refused link must be listed, got %v", refused)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user