Initial curated RAGcore source from c16667f0c9397e2bfc8dd0255b114fba23c8d05e
This commit is contained in:
commit
7ca726caf2
659 files changed
+98171
No files matched your search
@@ -0,0 +1,176 @@
|
||||
"""The filesystem allowlist: which server-side paths a source may ever read.
|
||||
|
||||
Rejecting traversal, symlinks and relative paths only proves a path is well
|
||||
formed. These tests are about the separate question the allowlist answers --
|
||||
whether a well-formed path is one an operator ever intended RAGcore to read.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from ragcore.domain.sources import (
|
||||
SourceRootError,
|
||||
assert_within_allowed_roots,
|
||||
normalize_allowed_roots,
|
||||
resolve_within_allowed_roots,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.security
|
||||
|
||||
_ROOTS = (Path("/mnt/rag-sources"), Path("/srv/corpora"))
|
||||
|
||||
|
||||
def test_no_configured_roots_allows_nothing() -> None:
|
||||
"""Fail closed. An empty allowlist is a real answer -- "this deployment
|
||||
reads no server-side paths" -- not a missing one to be defaulted away."""
|
||||
|
||||
with pytest.raises(SourceRootError, match="no allowed source roots"):
|
||||
assert_within_allowed_roots("/mnt/rag-sources/runbooks", ())
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"requested",
|
||||
[
|
||||
"/mnt/rag-sources",
|
||||
"/mnt/rag-sources/runbooks",
|
||||
"/mnt/rag-sources/runbooks/fleet",
|
||||
"/srv/corpora/handbook",
|
||||
],
|
||||
)
|
||||
def test_a_root_and_anything_below_it_is_allowed(requested: str) -> None:
|
||||
assert assert_within_allowed_roots(requested, _ROOTS) == Path(requested)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"requested",
|
||||
[
|
||||
"/etc",
|
||||
"/etc/shadow",
|
||||
"/app/src/ragcore/config.py",
|
||||
"/var/lib/postgresql/data",
|
||||
"/mnt",
|
||||
"/",
|
||||
],
|
||||
)
|
||||
def test_a_path_outside_every_root_is_refused(requested: str) -> None:
|
||||
with pytest.raises(SourceRootError, match="outside every allowed source root"):
|
||||
assert_within_allowed_roots(requested, _ROOTS)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"requested",
|
||||
[
|
||||
"/mnt/rag-sources-secret",
|
||||
"/mnt/rag-sources-secret/keys",
|
||||
"/srv/corpora-backup",
|
||||
],
|
||||
)
|
||||
def test_a_sibling_sharing_a_string_prefix_is_not_contained(requested: str) -> None:
|
||||
"""Containment is decided on path *components*, never on string prefixes.
|
||||
``/mnt/rag-sources`` does not contain ``/mnt/rag-sources-secret``, however
|
||||
much the two look alike to ``startswith``."""
|
||||
|
||||
with pytest.raises(SourceRootError, match="outside every allowed source root"):
|
||||
assert_within_allowed_roots(requested, _ROOTS)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"requested",
|
||||
["relative/path", "", "rag-sources", "C:x"],
|
||||
)
|
||||
def test_a_path_that_is_not_absolute_is_refused(requested: str) -> None:
|
||||
with pytest.raises(SourceRootError):
|
||||
assert_within_allowed_roots(requested, _ROOTS)
|
||||
|
||||
|
||||
def test_traversal_is_refused_before_containment_is_even_considered() -> None:
|
||||
"""``/mnt/rag-sources/../../etc`` normalises to ``/etc``, so a check that
|
||||
normalised first and compared second would be fine either way -- but the
|
||||
path is rejected outright, so a root that happens to be near the top of
|
||||
the tree cannot be walked out of."""
|
||||
|
||||
with pytest.raises(SourceRootError, match="must not traverse"):
|
||||
assert_within_allowed_roots("/mnt/rag-sources/../../etc", _ROOTS)
|
||||
|
||||
|
||||
def test_a_nul_byte_is_refused() -> None:
|
||||
with pytest.raises(SourceRootError, match="NUL-free"):
|
||||
assert_within_allowed_roots("/mnt/rag-sources/x\x00.txt", _ROOTS)
|
||||
|
||||
|
||||
def test_the_stored_spelling_survives_validation() -> None:
|
||||
"""The API host validating a POSIX deployment path must hand back exactly
|
||||
what the operator wrote: a Windows-side ``normpath`` would rewrite it into
|
||||
something the Linux worker could never open."""
|
||||
|
||||
assert str(assert_within_allowed_roots("/mnt/rag-sources/docs", _ROOTS)).replace(
|
||||
"\\", "/"
|
||||
) == "/mnt/rag-sources/docs"
|
||||
|
||||
|
||||
# -- operator-configured roots ----------------------------------------------
|
||||
|
||||
|
||||
def test_a_filesystem_root_may_not_be_an_allowed_root() -> None:
|
||||
"""Allowing ``/`` would make the allowlist meaningless."""
|
||||
|
||||
with pytest.raises(SourceRootError, match="must not be a filesystem root"):
|
||||
normalize_allowed_roots(["/"])
|
||||
|
||||
|
||||
def test_a_relative_or_traversing_root_is_refused_at_startup() -> None:
|
||||
with pytest.raises(SourceRootError, match="absolute"):
|
||||
normalize_allowed_roots(["mnt/rag-sources"])
|
||||
with pytest.raises(SourceRootError, match="traverse"):
|
||||
normalize_allowed_roots(["/mnt/rag-sources/../.."])
|
||||
|
||||
|
||||
def test_duplicate_roots_collapse() -> None:
|
||||
assert normalize_allowed_roots(["/mnt/rag", "/mnt/rag"]) == (Path("/mnt/rag"),)
|
||||
|
||||
|
||||
# -- filesystem truth --------------------------------------------------------
|
||||
|
||||
|
||||
def test_resolution_rejects_a_path_that_does_not_exist(tmp_path: Path) -> None:
|
||||
"""The worker's check is about the filesystem as it is: a lexically fine
|
||||
path that cannot be resolved is not a path it may read."""
|
||||
|
||||
with pytest.raises(SourceRootError, match="cannot be resolved"):
|
||||
resolve_within_allowed_roots(tmp_path / "absent", (tmp_path,))
|
||||
|
||||
|
||||
def test_resolution_accepts_a_real_directory_inside_an_allowed_root(tmp_path: Path) -> None:
|
||||
allowed = tmp_path / "corpora"
|
||||
inside = allowed / "runbooks"
|
||||
inside.mkdir(parents=True)
|
||||
|
||||
assert resolve_within_allowed_roots(inside, (allowed,)) == inside.resolve(strict=True)
|
||||
|
||||
|
||||
def test_resolution_refuses_a_real_directory_outside_every_allowed_root(tmp_path: Path) -> None:
|
||||
allowed = tmp_path / "corpora"
|
||||
allowed.mkdir()
|
||||
elsewhere = tmp_path / "secrets"
|
||||
elsewhere.mkdir()
|
||||
|
||||
with pytest.raises(SourceRootError, match="outside every allowed source root"):
|
||||
resolve_within_allowed_roots(elsewhere, (allowed,))
|
||||
|
||||
|
||||
def test_an_unmounted_root_contains_nothing_but_does_not_break_the_others(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""A deployment may configure roots that only some containers mount. One
|
||||
that is absent here simply cannot contain anything; the roots that are
|
||||
present still get their chance."""
|
||||
|
||||
allowed = tmp_path / "corpora"
|
||||
allowed.mkdir()
|
||||
|
||||
assert resolve_within_allowed_roots(
|
||||
allowed, (tmp_path / "never-mounted", allowed)
|
||||
) == allowed.resolve(strict=True)
|
||||
Reference in new issue
Block a user