frontend: tighten extraFiles target type to strMatching regex
damocles suggested using lib.types.strMatching for the target option itself rather than relying solely on the post-hoc assertion. Pattern: `^[A-Za-z0-9_][A-Za-z0-9_./-]*$` — first char alphanumeric/_, then alphanumerics + _ + . + / + - allowed (so nested layouts like "games/bitburner" still work). This rejects at type-check time: - leading `/` (absolute paths) - leading `.` (so `..` as a full string blocked, also `./foo`) - leading `-` (would parse as flag by some tools) - spaces, control chars, weird unicode The existing assertion stays — it catches mid-path `..` segments (`foo/../bar`) that the regex can't reject without lookahead. POSIX regex (which nix uses) doesn't support lookahead, so the type-and-assertion split is the cleanest expression. Refs #273.
This commit is contained in:
parent
2951da32e7
commit
65532e8387
1 changed files with 24 additions and 12 deletions
|
|
@ -192,7 +192,15 @@
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
target = lib.mkOption {
|
target = lib.mkOption {
|
||||||
type = lib.types.str;
|
# First char must be alphanumeric/underscore (rules out
|
||||||
|
# leading `/`, leading `.`, leading `-`); inner chars
|
||||||
|
# include `.` and `/` so nested layouts like
|
||||||
|
# `"games/bitburner"` work. This is the shape check —
|
||||||
|
# the `..`-segment traversal check is the assertion in
|
||||||
|
# `config.assertions` below (regex alone can't reject
|
||||||
|
# mid-path `..` segments without lookahead, which nix
|
||||||
|
# POSIX regex doesn't support).
|
||||||
|
type = lib.types.strMatching "^[A-Za-z0-9_][A-Za-z0-9_./-]*$";
|
||||||
default = name;
|
default = name;
|
||||||
defaultText = lib.literalMD "the attribute name";
|
defaultText = lib.literalMD "the attribute name";
|
||||||
description = ''
|
description = ''
|
||||||
|
|
@ -201,6 +209,11 @@
|
||||||
the on-disk layout in the merged derivation. Defaults
|
the on-disk layout in the merged derivation. Defaults
|
||||||
to the attribute name. Use forward slashes for
|
to the attribute name. Use forward slashes for
|
||||||
nested layouts (e.g. `"games/bitburner"`).
|
nested layouts (e.g. `"games/bitburner"`).
|
||||||
|
|
||||||
|
Constrained shape: must start with an alphanumeric or
|
||||||
|
`_`, and only contain alphanumerics, `_`, `.`, `/`,
|
||||||
|
`-`. `..` segments are separately rejected at config
|
||||||
|
eval time.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -452,21 +465,20 @@
|
||||||
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
|
# hyperhive.frontend.extraFiles[*].target is concatenated into
|
||||||
# $out during the mergedDist build. Reject path traversal
|
# $out during the mergedDist build. The option's strMatching
|
||||||
# (`..` segments) and absolute paths (leading `/`) — both would
|
# type already rejects leading `/`, leading `.`, and the
|
||||||
# let an entry escape the static dir. agent.nix is operator-
|
# weirder characters; this assertion catches mid-path `..`
|
||||||
# reviewed, so this is belt-and-braces, but it's the kind of
|
# segments (e.g. `foo/../etc/passwd`) that the type's regex
|
||||||
# mistake that's easy to make and hard to spot during review.
|
# can't easily express without lookahead. 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.
|
||||||
{
|
{
|
||||||
assertion = lib.all (
|
assertion = lib.all (
|
||||||
entry:
|
entry: !(builtins.any (seg: seg == "..") (lib.splitString "/" entry.target))
|
||||||
!(lib.hasPrefix "/" entry.target)
|
|
||||||
&& !(builtins.any (seg: seg == "..") (lib.splitString "/" entry.target))
|
|
||||||
) (lib.attrValues config.hyperhive.frontend.extraFiles);
|
) (lib.attrValues config.hyperhive.frontend.extraFiles);
|
||||||
message = ''
|
message = ''
|
||||||
hyperhive.frontend.extraFiles: `target` must be a relative
|
hyperhive.frontend.extraFiles: `target` must not contain
|
||||||
path inside the static dir — no leading `/`, no `..`
|
`..` path segments.
|
||||||
segments.
|
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue