T09 · Insecure Skill Coding Practices
- Location
scripts/openclaw_cron_health_check.py:125- Finding
Allowlisted diagnostic commands are vulnerable to executable PATH hijacking
- Content
View full analysis
Vulnerability Details
File Location:
scripts/openclaw_cron_health_check.py:125-143andscripts/openclaw_cron_health_check.py:177
Vulnerability Type: Untrusted executable resolution through the inheritedPATH
Risk Level: MediumVulnerable Code
python def validate_runnable_command(command: Any, cfg: dict[str, Any]) -> tuple[list[str], str | None]: argv, cwd = command_argv(command) base = os.path.basename(argv[0]) if base in BLOCKED_BINS: raise ValueError(f"blocked command: {base}") if argv[0].startswith("/"): raise ValueError("absolute command paths are not supported by the portable checker") if not is_safe_builtin_argv(argv): raise ValueError(f"argv is not in the non-mutating diagnostic allowlist: {command_label(command)}") return argv, cwd def run(command: Any, cfg: dict[str, Any], timeout: int = 20) -> tuple[int, str, str]: try: argv, cwd = validate_runnable_command(command, cfg) proc = subprocess.run( argv, check=False, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout, cwd=cwd, )The command existence check uses the same environment-dependent resolution:
python return ("OK", "binary exists") if shutil.which(argv[0]) else ("CRITICAL", f"binary missing: {argv[0]}")Technical Analysis
The checker restricts command arguments to fixed, non-mutating forms, including
openclaw,crontab, andsystemctl. This effectively prevents arbitrary command selection through the configuration. However, it executes these commands by bare executable name and therefore delegates executable resolution to the inheritedPATH.Absolute executable paths are explicitly rejected, while the script does not:
- Replace
PATHwith a trusted, minimal search path. - Verify that th ...[truncated 2575 chars]
- Replace
- Remediation
View remediation
Remediation Suggestions
- Resolve each permitted utility to a trusted absolute path during installation or setup, such as a deployment-specific path for
openclawand platform-appropriate paths forcrontabandsystemctl. - Permit absolute paths only after validating that the resolved basename and complete argument vector match the intended allowlist.
- Verify that each executable:
- Is a regular file.
- Is owned by root or another explicitly trusted account.
- Is not writable by group or other users.
- Resides under directories that are also not writable by untrusted users.
- Execute the verified absolute path rather than resolving the command name again through
PATH. - Pass a minimal sanitized environment to
subprocess.run(). At minimum, define a trustedPATHand remove environment variables capable of altering executable or library loading. - Fail closed if a utility cannot be resolved uniquely to an approved path.
- Document the resolved executable paths in the instance-specific configuration and verify them during the manual pre-scheduling validation.
- Run the recurring health check using a dedicated, non-privileged account with read access only to the metadata and logs necessary for the report.
- Resolve each permitted utility to a trusted absolute path during installation or setup, such as a deployment-specific path for
