mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-15 03:55:09 +08:00
fix(wiki): add fail-closed option for empty source-path allow-list
This commit is contained in:
parent
56b49e9cbf
commit
4c56df2ed3
@ -80,6 +80,16 @@ public class WikiProperties {
|
|||||||
*/
|
*/
|
||||||
private java.util.List<String> allowedSourceRoots = new java.util.ArrayList<>();
|
private java.util.List<String> allowedSourceRoots = new java.util.ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fail-closed switch for source-path validation. When {@code true} and
|
||||||
|
* {@link #allowedSourceRoots} is empty, every source directory is rejected
|
||||||
|
* (no path is allowed until a root is configured) — recommended for
|
||||||
|
* multi-tenant servers so a missing allow-list cannot silently re-open
|
||||||
|
* full-filesystem reads. Default {@code false} keeps the opt-in behaviour
|
||||||
|
* for desktop / single-tenant where no roots are configured.
|
||||||
|
*/
|
||||||
|
private boolean requireAllowedRoots = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When {@code true}, a scheduled job (single-owner via ShedLock) scans each
|
* When {@code true}, a scheduled job (single-owner via ShedLock) scans each
|
||||||
* KB's configured source directory and auto-ingests new files. Off by
|
* KB's configured source directory and auto-ingests new files. Off by
|
||||||
|
|||||||
@ -47,6 +47,11 @@ public class WikiSourcePathValidator {
|
|||||||
Path resolved = canonicalize(Paths.get(rawPath));
|
Path resolved = canonicalize(Paths.get(rawPath));
|
||||||
List<String> roots = properties.getAllowedSourceRoots();
|
List<String> roots = properties.getAllowedSourceRoots();
|
||||||
if (roots == null || roots.isEmpty()) {
|
if (roots == null || roots.isEmpty()) {
|
||||||
|
if (properties.isRequireAllowedRoots()) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"No allowed source roots are configured; refusing the path (fail-closed). "
|
||||||
|
+ "Set mate.wiki.allowed-source-roots to permit directories.");
|
||||||
|
}
|
||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
for (String root : roots) {
|
for (String root : roots) {
|
||||||
|
|||||||
@ -27,6 +27,12 @@ class WikiSourcePathValidatorTest {
|
|||||||
return new WikiSourcePathValidator(props);
|
return new WikiSourcePathValidator(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private WikiSourcePathValidator failClosedValidator() {
|
||||||
|
WikiProperties props = new WikiProperties();
|
||||||
|
props.setRequireAllowedRoots(true);
|
||||||
|
return new WikiSourcePathValidator(props);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void blankPath_rejected() {
|
void blankPath_rejected() {
|
||||||
assertThrows(IllegalArgumentException.class, () -> validator(List.of()).validateDirectory(" "));
|
assertThrows(IllegalArgumentException.class, () -> validator(List.of()).validateDirectory(" "));
|
||||||
@ -38,6 +44,13 @@ class WikiSourcePathValidatorTest {
|
|||||||
assertEquals(tmp.toRealPath(), resolved);
|
assertEquals(tmp.toRealPath(), resolved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void emptyRoots_failClosed_rejectsEverything(@TempDir Path tmp) {
|
||||||
|
// With require-allowed-roots enabled, an empty allow-list denies all.
|
||||||
|
assertThrows(IllegalArgumentException.class,
|
||||||
|
() -> failClosedValidator().validateDirectory(tmp.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void insideAllowedRoot_isAccepted(@TempDir Path root) throws IOException {
|
void insideAllowedRoot_isAccepted(@TempDir Path root) throws IOException {
|
||||||
Path sub = Files.createDirectory(root.resolve("kb-source"));
|
Path sub = Files.createDirectory(root.resolve("kb-source"));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user