fix: close server bypass edge cases

This commit is contained in:
2026-08-05 12:09:32 +02:00
parent a94affd6ac
commit fc349e634c
9 changed files with 296 additions and 148 deletions
+36 -1
View File
@@ -36,6 +36,10 @@ for fixture in \
done
server_guide="$root/docs/install/server.md"
grep -Eq '^sudo install -d -o 10001 -g thothii-ops -m 2750 /srv/thothii$' "$server_guide" || {
echo "server operations guide does not set the parent traversal boundary" >&2
exit 1
}
for required in \
'thothii-ops' \
'THT_BACKUP_ROOT=/srv/thothii-backups' \
@@ -101,7 +105,8 @@ sed '/^case "\$mode" in/,$d' "$root/scripts/verify-workspace-install-docs.sh" >"
source "$verifier_functions"
adapted_reorder="$negative_root/caddy-adapted-reorder.json"
node - "$adapted_reorder" <<'NODE'
adapted_bypass="$negative_root/caddy-adapted-bypass.json"
node - "$adapted_reorder" "$adapted_bypass" <<'NODE'
const fs = require("fs");
const publicHeaders = [
"X-Thoth-Principal-Issuer", "X-Thoth-Principal-Subject",
@@ -123,6 +128,12 @@ const document = {routes: [{handle: [
{handler: "reverse_proxy", upstreams: [{dial: "127.0.0.1:8080"}]},
]}]};
fs.writeFileSync(process.argv[2], JSON.stringify(document));
const frontend = {handler: "reverse_proxy", upstreams: [{dial: "127.0.0.1:8080"}]};
const validChain = [...publicHeaders, ...trustedHeaders].map(clear).concat(auth, frontend);
fs.writeFileSync(process.argv[3], JSON.stringify({routes: [
{handle: validChain},
{handle: [frontend]},
]}));
NODE
adapted_output="$negative_root/caddy-adapted-output"
set +e
@@ -135,6 +146,16 @@ if [[ $adapted_status -eq 0 ]] || ! grep -Fq "Caddy adapted identity clears must
exit 1
fi
set +e
verify_caddy_adapted_identity_order "$adapted_bypass" >"$adapted_output" 2>&1
adapted_status=$?
set -e
if [[ $adapted_status -eq 0 ]] || ! grep -Fq "Caddy adapted frontend path bypasses complete authentication contract" "$adapted_output"; then
echo "Caddy additional direct frontend route fixture was not rejected correctly" >&2
cat "$adapted_output" >&2
exit 1
fi
negative_failures=0
expect_guide_rejected() {
local label="$1" validator="$2" source_guide="$3" relative_path="$4"
@@ -180,6 +201,9 @@ switch (mutation) {
case "server-host-loopback":
changed += "\nFor host-gateway, keep the external service listening on 127.0.0.1.\n";
break;
case "server-parent-traversal":
changed = original.replace("sudo install -d -o 10001 -g thothii-ops -m 2750 /srv/thothii\n", "");
break;
case "server-raw-remove":
changed += "\n```sh\ndocker rm thothii-core thothii-frontend\n```\n";
break;
@@ -218,6 +242,9 @@ switch (mutation) {
changed = changed.slice(0, frontendAt) + clear + "\n" + clear + changed.slice(frontendAt + clear.length);
break;
}
case "nginx-additional-bypass":
changed = original.replace(" location / {", " location /bypass {\n proxy_pass http://127.0.0.1:8080;\n }\n\n location / {");
break;
case "caddy-no-auth":
changed = original.replace("forward_auth auth-gateway:4180 {", "# forward authentication omitted");
break;
@@ -333,6 +360,10 @@ expect_guide_rejected \
"server host-gateway loopback listener" verify_server_guide \
"$root/docs/install/server.md" docs/install/server.md server-host-loopback \
"server host-gateway guidance assumes a host loopback listener"
expect_guide_rejected \
"server parent traversal boundary" verify_server_guide \
"$root/docs/install/server.md" docs/install/server.md server-parent-traversal \
"server installation guide does not set parent traversal boundary"
expect_guide_rejected \
"server raw container removal" verify_server_guide \
"$root/docs/install/server.md" docs/install/server.md server-raw-remove \
@@ -377,6 +408,10 @@ expect_guide_rejected \
"Nginx admin clear moved out of auth scope" verify_reverse_proxy_nginx_guide \
"$root/docs/install/reverse-proxy-nginx.md" docs/install/reverse-proxy-nginx.md nginx-admin-clear-wrong-scope \
"Nginx auth location does not clear inbound admin identity"
expect_guide_rejected \
"Nginx additional frontend bypass location" verify_reverse_proxy_nginx_guide \
"$root/docs/install/reverse-proxy-nginx.md" docs/install/reverse-proxy-nginx.md nginx-additional-bypass \
"Nginx frontend upstream location bypasses complete authentication contract"
expect_guide_rejected \
"Caddy identity without authentication" verify_reverse_proxy_caddy_guide \
"$root/docs/install/reverse-proxy-caddy.md" docs/install/reverse-proxy-caddy.md caddy-no-auth \