v0.328.0 (unreleased): security review round 3 — under HDD_PATH only appdata/ is a data root (not backups/)
gates / gates (push) Successful in 45s
gates / gates (push) Successful in 45s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
1 parent
36c4aa4e69
commit
09ac87a843
3 files changed
+22
No files matched your search
@@ -48,6 +48,11 @@ still refuses and the app page still says so.
|
|||||||
options (or a non-root one in its target) is refused. The catalog reader refuses YAML anchors, aliases and merge keys
|
options (or a non-root one in its target) is refused. The catalog reader refuses YAML anchors, aliases and merge keys
|
||||||
(the box's YAML library expands them, the reader would judge a different document). Red-proved
|
(the box's YAML library expands them, the reader would judge a different document). Red-proved
|
||||||
(`P2/redproof-security-review-round2.txt`).
|
(`P2/redproof-security-review-round2.txt`).
|
||||||
|
- **Security review round 3:** under `${HDD_PATH}` only `appdata/` is a data root — the drive namespace's `backups/`
|
||||||
|
(recovery units with the apps' portable secrets) and its other top-level folders are siblings no app may bind; the
|
||||||
|
household's folders come through `${USERDATA_PATH}`. Every catalog bind already uses `${HDD_PATH}/appdata/…`.
|
||||||
|
Known limit, stated: one app can still name ANOTHER app's `appdata/<name>` (paperless-ngx's folder is `paperless`,
|
||||||
|
so a per-app rule needs a name map) — filed. Red-proved (`P2/redproof-security-review-round3.txt`).
|
||||||
|
|
||||||
## v0.327.1 — files.<domain> reaches FileBrowser again: a file route by name, not Docker labels (2026-10-17)
|
## v0.327.1 — files.<domain> reaches FileBrowser again: a file route by name, not Docker labels (2026-10-17)
|
||||||
|
|
||||||
|
|||||||
@@ -512,6 +512,12 @@ func (c *checker) validRoots() []string {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(v, DriveNamespace) || (c.p.SystemDataPath != "" && within(v, filepath.Clean(c.p.SystemDataPath))) {
|
if strings.HasPrefix(v, DriveNamespace) || (c.p.SystemDataPath != "" && within(v, filepath.Clean(c.p.SystemDataPath))) {
|
||||||
|
if r == "HDD_PATH" {
|
||||||
|
// round 3: HDD_PATH is the drive's whole namespace — its backups/ (recovery units carry app secrets)
|
||||||
|
// and every other top-level folder are siblings an app has no business binding. Only appdata/ is a
|
||||||
|
// root; the household's folders come through USERDATA_PATH.
|
||||||
|
v = filepath.Join(v, "appdata")
|
||||||
|
}
|
||||||
out = append(out, v)
|
out = append(out, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -406,3 +406,14 @@ func TestAdmit_ANotYetCreatedPathBehindASymlink(t *testing.T) {
|
|||||||
t.Fatal("a resolve error other than not-exist was admitted (fail open)")
|
t.Fatal("a resolve error other than not-exist was admitted (fail open)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Round 3: ${HDD_PATH} itself and its siblings of appdata/ (backups/ — the recovery units with app secrets) are no
|
||||||
|
// root; ${HDD_PATH}/appdata/... is.
|
||||||
|
func TestAdmit_HDDPathRootIsAppdataOnly(t *testing.T) {
|
||||||
|
for _, line := range []string{" - ${HDD_PATH}:/drive\n", " - ${HDD_PATH}/backups:/b\n", " - ${HDD_PATH}/appdata-x:/b\n"} {
|
||||||
|
compose := strings.Replace(base, " - app_data:/data\n", " - app_data:/data\n"+line, 1)
|
||||||
|
if err := admit(t, "app", compose, env()); err == nil {
|
||||||
|
t.Fatalf("%q was admitted", line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user