feat: harden community production foundation through story 1.5
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
SCRIPT = Path(__file__).parents[2] / "scripts/check-config-boundaries.py"
|
||||
|
||||
|
||||
class ConfigBoundaryTests(unittest.TestCase):
|
||||
def run_check(self, root: Path, *files: str) -> subprocess.CompletedProcess[str]:
|
||||
return subprocess.run(
|
||||
["python3", str(SCRIPT), "--root", str(root), "--files", *files],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
|
||||
def test_value_only_production_code_passes(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
path = root / "crates/example/src/lib.rs"
|
||||
path.parent.mkdir(parents=True)
|
||||
path.write_text("pub fn configured(value: u32) -> u32 { value }\n", encoding="utf-8")
|
||||
result = self.run_check(root, "crates/example/src/lib.rs")
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
|
||||
def test_direct_alias_and_hidden_reader_forms_fail(self) -> None:
|
||||
cases = (
|
||||
"std::env::var(\"X\")",
|
||||
"std /* split */ ::\n env :: var(\"X\")",
|
||||
"use std::env as process_environment;",
|
||||
"use std::{collections::BTreeMap, env};",
|
||||
"pub use std :: env :: var as exported_reader;",
|
||||
"use std as standard; standard :: env :: var(\"X\");",
|
||||
"extern crate std as standard; standard::env::vars();",
|
||||
"use std::{self as system}; system::env::var(\"X\");",
|
||||
"env::vars_os()",
|
||||
"fn community_from_env() {}",
|
||||
"dotenvy::dotenv()",
|
||||
"option_env!(\"SECRET\")",
|
||||
"env!(\"SECRET\")",
|
||||
)
|
||||
for index, source in enumerate(cases):
|
||||
with self.subTest(source=source), tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
relative = f"crates/example/src/case_{index}.rs"
|
||||
path = root / relative
|
||||
path.parent.mkdir(parents=True)
|
||||
path.write_text(source, encoding="utf-8")
|
||||
result = self.run_check(root, relative)
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
|
||||
def test_only_package_version_compile_time_macro_is_allowed(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
relative = "apps/example/src/main.rs"
|
||||
path = root / relative
|
||||
path.parent.mkdir(parents=True)
|
||||
path.write_text(
|
||||
'const VERSION: &str = env! ( "CARGO_PKG_VERSION" );\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
result = self.run_check(root, relative)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
|
||||
def test_command_line_arguments_are_not_environment_configuration(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
relative = "apps/example/src/main.rs"
|
||||
path = root / relative
|
||||
path.parent.mkdir(parents=True)
|
||||
path.write_text(
|
||||
"fn main() { let _ = std::env::args().next(); }\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
result = self.run_check(root, relative)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
|
||||
def test_comments_and_strings_do_not_trigger_false_positives(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
relative = "crates/example/src/lib.rs"
|
||||
path = root / relative
|
||||
path.parent.mkdir(parents=True)
|
||||
path.write_text(
|
||||
'// std::env::var("X")\nconst NOTE: &str = "option_env!(\\\"X\\\")";\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
result = self.run_check(root, relative)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
|
||||
def test_missing_traversal_and_symlink_paths_fail_closed(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
outside = root.parent / "config-boundary-outside.rs"
|
||||
outside.write_text("std::env::var(\"X\");", encoding="utf-8")
|
||||
self.addCleanup(outside.unlink, missing_ok=True)
|
||||
for supplied in ("missing.rs", "../config-boundary-outside.rs"):
|
||||
result = self.run_check(root, supplied)
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
link = root / "link.rs"
|
||||
link.symlink_to(outside)
|
||||
result = self.run_check(root, "link.rs")
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
|
||||
def test_default_scan_covers_build_scripts_and_rejects_symlinks(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
build = root / "crates/example/build.rs"
|
||||
build.parent.mkdir(parents=True)
|
||||
build.write_text('std::env::var("X");', encoding="utf-8")
|
||||
result = subprocess.run(
|
||||
["python3", str(SCRIPT), "--root", str(root)],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
|
||||
build.unlink()
|
||||
outside = root / "outside.rs"
|
||||
outside.write_text("fn safe() {}", encoding="utf-8")
|
||||
link = root / "apps/example/src/link.rs"
|
||||
link.parent.mkdir(parents=True)
|
||||
link.symlink_to(outside)
|
||||
result = subprocess.run(
|
||||
["python3", str(SCRIPT), "--root", str(root)],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user