fix(web): require clone dir strictly under build_vms on remove (W6)
remove_vm() deletes vmx.parent, so containment must check the clone dir, not just the vmx: a crafted vmx_id of build_vms/x.vmx passed the old check and would rmtree the entire clone base. Now the parent must be strictly inside build_vms.
This commit is contained in:
@@ -356,6 +356,38 @@ def test_vm_remove_outside_build_vms_is_400_and_does_not_delete(tmp_path: Path)
|
||||
assert not any(e.result == "ok" for e in entries)
|
||||
|
||||
|
||||
def test_vm_remove_vmx_directly_in_build_vms_is_400_not_wiping_base(tmp_path: Path) -> None:
|
||||
"""A vmx whose parent IS build_vms would rmtree the whole clone base -- reject.
|
||||
|
||||
remove_vm() deletes vmx.parent; for ``build_vms/x.vmx`` that parent is
|
||||
build_vms itself. The containment check must reject it so a crafted
|
||||
vmx_id can't wipe every clone at once.
|
||||
"""
|
||||
config = _make_config(tmp_path)
|
||||
build_vms = config.paths.build_vms
|
||||
build_vms.mkdir(parents=True, exist_ok=True)
|
||||
survivor = build_vms / "Clone_keep"
|
||||
survivor.mkdir()
|
||||
(survivor / "Clone_keep.vmx").write_text("keep", encoding="utf-8")
|
||||
|
||||
danger_vmx = build_vms / "x.vmx" # parent == build_vms itself
|
||||
danger_vmx.write_text("x", encoding="utf-8")
|
||||
|
||||
fake_backend = _FakeBackend([])
|
||||
app = create_app(config)
|
||||
app.dependency_overrides[get_backend] = lambda: fake_backend
|
||||
client = TestClient(app)
|
||||
csrf = _get_csrf(client)
|
||||
vmx_id = routes_module.encode_vmx_id(danger_vmx)
|
||||
|
||||
resp = client.post(f"/vms/{vmx_id}/remove", data={"csrf": csrf, "stage": "execute"})
|
||||
|
||||
assert resp.status_code == 400
|
||||
assert build_vms.exists() # clone base NOT wiped
|
||||
assert survivor.exists() # sibling clone survived
|
||||
assert fake_backend.delete_calls == []
|
||||
|
||||
|
||||
def test_vm_remove_malformed_vmx_id_is_400(tmp_path: Path) -> None:
|
||||
config = _make_config(tmp_path)
|
||||
app = create_app(config)
|
||||
|
||||
Reference in New Issue
Block a user