fix(release): confine all proxy temporary paths to bounded storage

This commit is contained in:
2026-10-14 08:21:52 +08:00
parent ef0ea71d0a
commit 83d3bf8309
3 changed files with 80 additions and 13 deletions
+58
View File
@@ -879,6 +879,64 @@ def test_proxy_is_separate_from_private_execution_control():
assert value["key_sha256"] not in contents
def test_all_enabled_nginx_temporary_paths_use_only_the_bounded_proxy_volume():
contents = proxy.render(
"sd-123456789abc",
{
"schema_version": 1,
"origin": "https://oj.test",
"certificate_sha256": "b" * 64,
"key_sha256": "c" * 64,
},
).decode()
paths = dict(re.findall(r"^\s+(\w+_temp_path) (\S+) 1 2;$", contents, re.M))
assert set(paths) == {
"client_body_temp_path",
"proxy_temp_path",
"fastcgi_temp_path",
"uwsgi_temp_path",
"scgi_temp_path",
}
assert {Path(value).parent for value in paths.values()} == {proxy_service.DATA}
assert "proxy_buffering off" in contents and "proxy_request_buffering off" in contents
@pytest.mark.parametrize("bad", ["wrong-mode", "link", "regular-file"])
def test_proxy_temp_directory_conflicts_are_not_overwritten(monkeypatch, tmp_path, bad):
monkeypatch.setattr(proxy_service, "DATA", tmp_path)
monkeypatch.setattr(proxy_service, "UID", os.getuid())
path = tmp_path / "body"
if bad == "wrong-mode":
path.mkdir(mode=0o755)
elif bad == "link":
path.symlink_to(tmp_path, target_is_directory=True)
else:
path.write_text("known conflict")
before = path.lstat()
with pytest.raises(policy.DeliveryError, match="unknown proxy temporary directory"):
proxy_install.temporary_directories()
after = path.lstat()
assert (before.st_ino, before.st_mode, before.st_uid) == (
after.st_ino,
after.st_mode,
after.st_uid,
)
def test_proxy_temp_directory_creation_is_bounded_and_repeatable(monkeypatch, tmp_path):
monkeypatch.setattr(proxy_service, "DATA", tmp_path)
monkeypatch.setattr(proxy_service, "UID", os.getuid())
monkeypatch.setattr(proxy_install.os, "chown", lambda *args: None)
proxy_install.temporary_directories()
before = {p.name: (p.stat().st_ino, stat.S_IMODE(p.stat().st_mode)) for p in tmp_path.iterdir()}
assert set(before) == {"body", "proxy", "fastcgi", "uwsgi", "scgi"}
assert all(mode == 0o700 for _, mode in before.values())
proxy_install.temporary_directories()
assert before == {
p.name: (p.stat().st_ino, stat.S_IMODE(p.stat().st_mode)) for p in tmp_path.iterdir()
}
def test_ordinary_units_bind_exact_batch_without_inline_secrets():
source, checksum = "123456789abc" + "d" * 28, "f" * 64
hashes = {name: "b" * 64 for name in configuration.CONFIG_FILES}
+4
View File
@@ -96,6 +96,10 @@ http {
client_body_timeout 10s;
client_body_buffer_size 16k;
client_body_temp_path /var/lib/kf-onlinejudge/proxy/body 1 2;
proxy_temp_path /var/lib/kf-onlinejudge/proxy/proxy 1 2;
fastcgi_temp_path /var/lib/kf-onlinejudge/proxy/fastcgi 1 2;
uwsgi_temp_path /var/lib/kf-onlinejudge/proxy/uwsgi 1 2;
scgi_temp_path /var/lib/kf-onlinejudge/proxy/scgi 1 2;
large_client_header_buffers 2 8k;
send_timeout 10s;
keepalive_timeout 15s;
+18 -13
View File
@@ -222,6 +222,23 @@ def check_binding(release: str, batch: str) -> dict:
return {"binding_valid": True, "tls_verified": False, "execution_verified": False}
def temporary_directories() -> None:
for name in ("body", "proxy", "fastcgi", "uwsgi", "scgi"):
temporary_directory = proxy_service.DATA / name
if temporary_directory.exists() or temporary_directory.is_symlink():
i = temporary_directory.lstat()
if (
not stat.S_ISDIR(i.st_mode)
or i.st_uid != proxy_service.UID
or i.st_gid != proxy_service.UID
or stat.S_IMODE(i.st_mode) != 0o700
):
raise DeliveryError("unknown proxy temporary directory")
else:
temporary_directory.mkdir(mode=0o700)
os.chown(temporary_directory, proxy_service.UID, proxy_service.UID)
def install_proxy(source: Path, expected: str, certificate: Path, key: Path) -> dict:
if os.getuid() != 0 or os.geteuid() != 0 or os.getgid() != 0:
raise DeliveryError("root proxy installer required")
@@ -319,19 +336,7 @@ def install_proxy(source: Path, expected: str, certificate: Path, key: Path) ->
install.directory(unitdir, 0o700)
install.exclusive_file(unitdir / "binding.json", canonical(selected), 0o600)
install.exclusive_file(unitdir / proxy_service.UNIT, proxy_service.render(selected), 0o644)
body = proxy_service.DATA / "body"
if body.exists() or body.is_symlink():
i = body.lstat()
if (
not stat.S_ISDIR(i.st_mode)
or i.st_uid != proxy_service.UID
or i.st_gid != proxy_service.UID
or stat.S_IMODE(i.st_mode) != 0o700
):
raise DeliveryError("unknown proxy temporary directory")
else:
body.mkdir(mode=0o700)
os.chown(body, proxy_service.UID, proxy_service.UID)
temporary_directories()
check_binding(selected["release_id"], selected["configuration_id"])
install.require_stopped()
if install.selection() != selected: