audit-labs/audit-tools

A collection of scripts, queries, and other goodies you can use in an audit. audit automation compliance evidence scripts

Commit 4867af4f3d

4867af4f3d6bc555da3464b9e9b9bfdff9a4416b

parent: 699513a1a7

Unsigned

cmc <hello@cleberg.net> · 2026-08-07 02:32 UTC

Harden CLI path handling and sample.html default RNG

SonarCloud security findings:
- load_config / load_json resolve and validate that the input path is a
  regular file before opening (pythonsecurity:S8707)
- sample.html seeds its default draw from crypto.getRandomValues instead of
  Math.random, and writes the seed back so the sample stays reproducible
  (javascript:S2245)

Layout: unified · split

applications/aws/aws_password_policy/evaluate_policy.py +4 −1
@@ -109,8 +109,11 @@ def evaluate(expect: Any | None, actual: Any, field_type: str) -> str:
109 109
110def load_json(path: Path) -> dict[str, Any]: 110def load_json(path: Path) -> dict[str, Any]:
111 """Read the JSON file generated by the Bash script.""" 111 """Read the JSON file generated by the Bash script."""
112 resolved = path.resolve()
113 if not resolved.is_file():
114 sys.exit(f"Could not read JSON file {path}: not a regular file")
112 try: 115 try:
113 with path.open("r", encoding="utf-8") as fh: 116 with resolved.open("r", encoding="utf-8") as fh:
114 return json.load(fh) 117 return json.load(fh)
115 except Exception as exc: 118 except Exception as exc:
116 sys.exit(f"Could not read JSON file {path}: {exc}") 119 sys.exit(f"Could not read JSON file {path}: {exc}")
sampling/sample.html +8 −1
@@ -77,7 +77,14 @@ function seededRandom(seed) {
77function handleFormSubmit(event) { 77function handleFormSubmit(event) {
78 event.preventDefault(); // Prevent the default form submission behavior 78 event.preventDefault(); // Prevent the default form submission behavior
79 const customSeedInput = document.getElementById('customSeed').value; 79 const customSeedInput = document.getElementById('customSeed').value;
80 const seed = customSeedInput ? parseInt(customSeedInput) : Math.floor(Math.random() * 1000000); // Use custom seed if provided 80 // Use the custom seed if provided; otherwise draw a strong random seed and
81 // write it back so the (reproducible) sample can always be tied to a seed.
82 const seed = customSeedInput
83 ? parseInt(customSeedInput)
84 : crypto.getRandomValues(new Uint32Array(1))[0] % 1000000;
85 if (!customSeedInput) {
86 document.getElementById('customSeed').value = seed;
87 }
81 generateSamples(seed); // Call the function with the seed 88 generateSamples(seed); // Call the function with the seed
82} 89}
83 90
sampling/sampling_tool/cli.py +3 −1
@@ -54,7 +54,9 @@ def load_config(path: str | None) -> dict[str, object]:
54 "YAML config support requires PyYAML. Install requirements.txt." 54 "YAML config support requires PyYAML. Install requirements.txt."
55 ) from exc 55 ) from exc
56 56
57 config_path = Path(path) 57 config_path = Path(path).resolve()
58 if not config_path.is_file():
59 raise AuditSamplingError(f"Config file not found: {path}")
58 with config_path.open("r", encoding="utf-8") as handle: 60 with config_path.open("r", encoding="utf-8") as handle:
59 data = yaml.safe_load(handle) or {} 61 data = yaml.safe_load(handle) or {}
60 if not isinstance(data, dict): 62 if not isinstance(data, dict):