Publish curated ITWorx_MCP_Hub source from ae713b53e32933192b7446ac25fd6394e69eb133
This commit is contained in:
1 parent
faa53707b9
commit
0086cafc87
4 files changed
+167
-4
No files matched your search
@@ -707,6 +707,7 @@ def test_scanner_stdout_bound_does_not_cap_or_capture_cache_files(tmp_path: Path
|
||||
def fake_scanner(command: list[str], **kwargs: object) -> subprocess.Popen[bytes]:
|
||||
assert "preexec_fn" not in kwargs
|
||||
assert kwargs.get("stdout") == subprocess.PIPE
|
||||
assert kwargs.get("umask") == 0o077
|
||||
code = (
|
||||
"from pathlib import Path; import os; "
|
||||
"Path('cache.bin').write_bytes(b'x' * (3 * 1024 * 1024)); "
|
||||
@@ -728,6 +729,7 @@ def test_scanner_stdout_bound_does_not_cap_or_capture_cache_files(tmp_path: Path
|
||||
|
||||
assert output == b'{"complete":true}'
|
||||
assert (tmp_path / "cache.bin").stat().st_size == 3 * 1024 * 1024
|
||||
assert (tmp_path / "cache.bin").stat().st_mode & 0o777 == 0o600
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
import os
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from scripts import build_mcp_hub_release_images as producer
|
||||
|
||||
|
||||
def test_database_download_child_has_private_umask_without_changing_other_stages(tmp_path):
|
||||
calls = []
|
||||
|
||||
def runner(command, **kwargs):
|
||||
calls.append(kwargs)
|
||||
return subprocess.CompletedProcess(command, 0)
|
||||
|
||||
for stage in ("trivy_db_download", "compose_local_build"):
|
||||
producer._execute(["fixture"], env={}, cwd=tmp_path, timeout=1, stage=stage, runner=runner)
|
||||
assert calls[0]["umask"] == 0o077
|
||||
assert "umask" not in calls[1]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"fault",
|
||||
[
|
||||
None,
|
||||
"owner",
|
||||
"symlink",
|
||||
"hardlink",
|
||||
"oversize",
|
||||
"parent",
|
||||
"db_link",
|
||||
"swap",
|
||||
"parent_swap",
|
||||
"after_swap",
|
||||
],
|
||||
)
|
||||
def test_db_metadata_adapter_restricts_only_owned_anchored_inode(monkeypatch, fault):
|
||||
def info(inode, mode, **extra):
|
||||
fields = dict(
|
||||
st_dev=1, st_ino=inode, st_mode=mode, st_uid=123, st_nlink=1, st_size=16, st_mtime_ns=1
|
||||
)
|
||||
fields.update(extra)
|
||||
return SimpleNamespace(**fields)
|
||||
|
||||
parent = info(1, stat.S_IFDIR | (0o755 if fault == "parent" else 0o700))
|
||||
db = info(2, stat.S_IFDIR | 0o755)
|
||||
metadata = info(3, stat.S_IFREG | 0o644)
|
||||
if fault == "owner":
|
||||
metadata.st_uid = 999
|
||||
if fault == "symlink":
|
||||
metadata.st_mode = stat.S_IFLNK | 0o644
|
||||
if fault == "hardlink":
|
||||
metadata.st_nlink = 2
|
||||
if fault == "oversize":
|
||||
metadata.st_size = 65537
|
||||
restricted = []
|
||||
closed = []
|
||||
opens = []
|
||||
successful = []
|
||||
cache = SimpleNamespace(lstat=lambda: parent)
|
||||
|
||||
def open_file(path, flags, *, dir_fd=None):
|
||||
opens.append((path, dir_fd))
|
||||
assert flags & 0x20000
|
||||
if path is cache:
|
||||
successful.append(10)
|
||||
return 10
|
||||
if path == "db":
|
||||
assert dir_fd == 10
|
||||
if fault == "db_link":
|
||||
raise OSError("fixture-private-value")
|
||||
successful.append(11)
|
||||
return 11
|
||||
assert path == "metadata.json" and dir_fd == 11
|
||||
successful.append(12)
|
||||
return 12
|
||||
|
||||
def fstat(fd):
|
||||
if fd == 10:
|
||||
return parent
|
||||
if fd == 11:
|
||||
return db
|
||||
if fault == "swap":
|
||||
return info(4, metadata.st_mode)
|
||||
return SimpleNamespace(**vars(metadata))
|
||||
|
||||
def inspect(path, *, dir_fd, follow_symlinks):
|
||||
assert follow_symlinks is False
|
||||
if path == "db":
|
||||
assert dir_fd == 10
|
||||
return info(4, db.st_mode) if fault == "parent_swap" else db
|
||||
assert path == "metadata.json" and dir_fd == 11
|
||||
return info(4, metadata.st_mode) if fault == "after_swap" and restricted else metadata
|
||||
|
||||
def restrict(fd, mode):
|
||||
assert fd == 12 and mode == 0o600
|
||||
restricted.append((fd, mode))
|
||||
metadata.st_mode = stat.S_IFREG | 0o600
|
||||
|
||||
monkeypatch.setattr(producer.platform, "system", lambda: "Linux")
|
||||
monkeypatch.setattr(producer, "_effective_uid", lambda: 123)
|
||||
monkeypatch.setattr(
|
||||
producer,
|
||||
"os",
|
||||
SimpleNamespace(
|
||||
O_RDONLY=os.O_RDONLY,
|
||||
O_DIRECTORY=0x10000,
|
||||
O_NOFOLLOW=0x20000,
|
||||
open=open_file,
|
||||
fstat=fstat,
|
||||
stat=inspect,
|
||||
fchmod=restrict,
|
||||
close=closed.append,
|
||||
),
|
||||
)
|
||||
if fault:
|
||||
with pytest.raises(producer.BuildRejected) as error:
|
||||
producer._private_db_metadata(cache)
|
||||
assert "fixture-private-value" not in str(error.value)
|
||||
if fault != "after_swap":
|
||||
assert restricted == []
|
||||
else:
|
||||
producer._private_db_metadata(cache)
|
||||
assert restricted == [(12, 0o600)]
|
||||
assert closed == list(reversed(successful))
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.name != "posix", reason="file-descriptor permission adapter requires Linux")
|
||||
def test_explicit_upstream_chmod_is_restricted_before_strict_json_reader(tmp_path):
|
||||
cache = tmp_path / "cache"
|
||||
db = cache / "db"
|
||||
db.mkdir(parents=True)
|
||||
cache.chmod(0o700)
|
||||
db.chmod(0o755)
|
||||
metadata = db / "metadata.json"
|
||||
metadata.write_text('{"Version":2}')
|
||||
metadata.chmod(0o644)
|
||||
with pytest.raises(producer.BuildRejected, match="not private and bounded"):
|
||||
producer._json_file(metadata, maximum=64 * 1024)
|
||||
producer._private_db_metadata(cache)
|
||||
assert metadata.stat().st_mode & 0o777 == 0o600
|
||||
assert producer._json_file(metadata, maximum=64 * 1024) == {"Version": 2}
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.name != "posix", reason="kernel umask requires Linux")
|
||||
def test_kernel_download_child_creates_private_files(tmp_path):
|
||||
command = [
|
||||
sys.executable,
|
||||
"-c",
|
||||
"from pathlib import Path; Path('metadata.json').write_text('{}')",
|
||||
]
|
||||
producer._execute(command, env=os.environ, cwd=tmp_path, timeout=10, stage="trivy_db_download")
|
||||
assert (tmp_path / "metadata.json").stat().st_mode & 0o777 == 0o600
|
||||
Reference in new issue
Block a user