Eval executes user-provided shell commands and reads arbitrary files as part of its evaluation checks. The following protections are in place:
is_command_safe() in src/checks.kujo blocks commands containing dangerous patterns:
rm -rf,sudo,chmod,curl | sh,wget | sh/dev/paths,mkfs,dd if=, fork bombsshutdown,reboot
Commands can also be restricted to an allowlist via the allowed_commands config field.
Additional command policy controls:
allowed_command_patterns: allow only commands matching approved substringsblocked_arg_patterns: deny commands containing blocked argument substrings even if base command is allowedcommand_pattern_match_mode: choosesubstring(default) ortokenmatching for allow/deny patternspolicy_profile: bootstrap secure defaults quickly (strict-ci,local-dev,release-gate)
Built-in command-name patterns are checked as complete token sequences, while
destructive shell and path fragments retain conservative substring matching.
This rejects commands such as nc without blocking benign path or argument
substrings that merely contain the same letters, such as concurrent.
is_path_safe() in src/checks.kujo restricts file access:
- Blocks
..path traversal - Blocks access to system directories (
/etc/,/root/,/var/,/tmp/) - Normalizes candidate and allowlisted paths before policy checks (handles
./, repeated/, trailing slashes) - Supports optional
allowed_pathsconfig for directory allowlisting
Path policy controls:
path_policy_mode: top-level path mode (openorallowlist-required)path_policy_profile: named path preset (open,ci-restricted,release-deny-default) that expandspath_policy_modeandallowed_pathspolicy_stage_overlays.<stage>.path_policy_mode: stage-specific path mode overridespolicy_stage_overlays.<stage>.path_policy_profile: stage-specific path preset for local/CI/release hardeningallowed_paths: explicit path allowlist for file-backed checks whenpath_policy_modeisallowlist-required
Eval is intended for controlled execution environments. For enterprise rollout, use defense-in-depth around the runtime:
- Isolated execution: run suites in ephemeral containers or isolated CI workers.
- Least privilege: mount only required directories and avoid privileged runner accounts.
- Policy-first suites: set suite-level
allowed_commands,allowed_command_patterns,blocked_arg_patterns,allowed_paths, andallowed_env_vars; only override per-test when necessary. - Stage path hardening: use
policy_stage_overlayswithpath_policy_profile: "ci-restricted"orpath_policy_profile: "release-deny-default"so CI and release stages apply stricter path boundaries than local runs. - Deterministic artifacts: write reports to unique per-run output directories and publish only required formats.
- Supervised process control: use external job timeouts/watchdogs to enforce hard preemption where required.
{
"allowed_commands": ["kujo", "echo", "cat"],
"allowed_command_patterns": ["kujo run", "kujo test", "echo "],
"blocked_arg_patterns": ["--privileged", "rm -rf", "curl |", "wget |"],
"path_policy_profile": "ci-restricted",
"allowed_paths": ["./eval_results", "./snapshots", "./fixtures"],
"allowed_env_vars": ["CI", "GITHUB_SHA", "GITHUB_REF"]
}env_var_equals supports optional allowlisting via allowed_env_vars.
- Suite-level
allowed_env_varsineval.jsonis threaded into env checks by default - Test-level
params.allowed_env_varsoverrides the suite-level allowlist for that check - Any
env_var_equalscheck targeting a variable outside the effective allowlist fails closed
redact_sensitive() in src/checks.kujo scrubs sensitive patterns from stdout/stderr:
- API key patterns (
sk-prefix) - Bearer tokens
- Password and secret parameters (
password=,secret=)
Optional audit telemetry:
redaction_audit_mode: trueincludesredaction_hitsandredaction_patternsin command-checkdetails- Useful for policy audits without exposing raw secret material
redact_output_patternssupports organization-specific additions (for example internal token prefixes) on top of built-in redaction rules
MAX_CONFIG_SIZE_BYTES: 1MB file size limit before parsingMAX_TESTS: 1000 test maximum per suiteMAX_STRING_LENGTH: 10K character limit on test names
execute_statusruns commands via the system shell — commands have access to the user's environment- Path validation blocks common attack vectors but is not a sandbox
http_getmay panic in interpreter mode (Kujo runtime quirk)- Timeout behavior depends on runtime support for
execute_statusoptions; validate timeout enforcement in your target Kujo build. - Output redaction uses simple pattern matching, not cryptographic guarantees
- Interpreter KUJORUN001 warnings may appear even when command exit codes are successful
To report a security issue, please open an issue on the GitHub repository with:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
Please allow reasonable time for fixes before public disclosure. Security issues in the check implementations themselves (not the Kujo runtime) will be addressed as priority.