frontend: tighten extraFiles target validation per damocles review
Follow-up to PR #350 review: 1. New assertion: hyperhive.frontend.extraFiles[*].target must be a relative path inside the static dir — leading '/' and '..' segments rejected at config eval time. Belt-and-braces against string-concat-into-paths escapes (the boundary doc flags this pattern even though agent.nix goes through operator review). 2. Documented overwrite semantics in the option doc: collision with a default-dist path or with a prior entry's target is a hard-fail (`refusing to overwrite existing path …`). To override a default file, fork `hyperhive.frontend.dist` instead — extraFiles is pure additions. The collision-hard-fail behaviour was already implemented in `mergedDist` (in commit a19e156); this commit just makes the contract explicit in the docstring. Refs #273, addresses damocles' notes on PR #350.
This commit is contained in:
parent
229c4292e9
commit
2951da32e7
1 changed files with 31 additions and 4 deletions
|
|
@ -224,10 +224,19 @@
|
||||||
the bitburner agent's game page at `/bitburner/`).
|
the bitburner agent's game page at `/bitburner/`).
|
||||||
|
|
||||||
The default agent UI remains served at `/`; entries here only
|
The default agent UI remains served at `/`; entries here only
|
||||||
add new routes and never replace the default. Path collisions
|
add new routes and never replace the default. Overwrite
|
||||||
with default-dist filenames are a configuration error and
|
semantics are **hard-fail**: if `target` collides with an
|
||||||
will surface as build failures (the merge derivation aborts
|
existing file or directory in the default dist (or with a
|
||||||
on overwrite).
|
prior entry's target), the `mergedDist` build aborts with
|
||||||
|
`refusing to overwrite existing path '<target>' in the
|
||||||
|
default dist`. To override a default file, fork the dist via
|
||||||
|
`hyperhive.frontend.dist` instead — `extraFiles` is for
|
||||||
|
pure additions.
|
||||||
|
|
||||||
|
`target` must be a relative path inside the static dir. An
|
||||||
|
assertion rejects leading `/` and `..` segments at config
|
||||||
|
eval time (string-concat-into-paths safety, even though
|
||||||
|
agent.nix goes through operator review before deploy).
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -442,6 +451,24 @@
|
||||||
|| lib.hasSuffix ".svg" (toString config.hyperhive.icon);
|
|| lib.hasSuffix ".svg" (toString config.hyperhive.icon);
|
||||||
message = "hyperhive.icon must point to an .svg file";
|
message = "hyperhive.icon must point to an .svg file";
|
||||||
}
|
}
|
||||||
|
# hyperhive.frontend.extraFiles[*].target is concatenated into
|
||||||
|
# $out during the mergedDist build. Reject path traversal
|
||||||
|
# (`..` segments) and absolute paths (leading `/`) — both would
|
||||||
|
# let an entry escape the static dir. agent.nix is operator-
|
||||||
|
# reviewed, so this is belt-and-braces, but it's the kind of
|
||||||
|
# mistake that's easy to make and hard to spot during review.
|
||||||
|
{
|
||||||
|
assertion = lib.all (
|
||||||
|
entry:
|
||||||
|
!(lib.hasPrefix "/" entry.target)
|
||||||
|
&& !(builtins.any (seg: seg == "..") (lib.splitString "/" entry.target))
|
||||||
|
) (lib.attrValues config.hyperhive.frontend.extraFiles);
|
||||||
|
message = ''
|
||||||
|
hyperhive.frontend.extraFiles: `target` must be a relative
|
||||||
|
path inside the static dir — no leading `/`, no `..`
|
||||||
|
segments.
|
||||||
|
'';
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
environment.etc."hyperhive/extra-mcp.json".text = builtins.toJSON config.hyperhive.extraMcpServers;
|
environment.etc."hyperhive/extra-mcp.json".text = builtins.toJSON config.hyperhive.extraMcpServers;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue