T07 · Tool Hijacking and Spoofing
Error
- Location
- linux_command_guard/checker.py:132
- Finding
- Allowlisted command names can resolve to attacker-controlled executables<![CDATA[ ## Vulnerability Details **File Location**: `linux_command_guard/parser.py:33-35`, `linux_command_guard/checker.py:132-139` **Vulnerability Type**: Executable path spoofing and security-policy bypass **Risk Level**: High ### Vulnerable Code ```python # linux_command_guard/parser.py:33-35 def parse_command(command: str) -> ParsedCommand: tokens = tokenize(command) base = next((token for token in tokens if token.strip()), None) return ParsedCommand(raw=command, tokens=tokens, base_command=base) ``` ```python # linux_command_guard/checker.py:132-139 if policy.allowlist and base not in policy.allowlist: return Decision( False, "Not in allowlist", matched_rule=base, base_command=base, details=(READ_ONLY_ALLOWLIST_GUIDANCE,), ) ``` ### Technical Analysis The allowlist validates only the textual value of the first command token, such as `ls`, `cat`, or `grep`. It does not resolve that name to an executable, constrain resolution to trusted system directories, or verify the resolved file's ownership and permissions. If a caller executes an approved command through a shell or a PATH-searching API such as `execvp`, the operating system may resolve the command to an attacker-controlled executable located earlier in `PATH`. Consequently, a malicious program named `ls` can satisfy the guard's allowlist even though it is unrelated to the trusted system utility. This is a trust-boundary problem: the checker authenticates a command name but not the executable that will actually receive control. The vulnerability becomes exploitable when an attacker can influence `PATH`, the working environment, or a directory appearing in `PATH`. ### Attack Path 1. The attacker obtains write access to a directory that is or can be placed before trusted directories in `PATH`. 2. The attacker creates an executable named after an allowlisted command, for example: ```bash mkdir -p /tmp/attacker-bin printf '#!/bi ...[truncated 1212 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Resolve allowlisted commands to canonical executable paths using a fixed, trusted search path rather than the caller's ambient `PATH`. 2. Define the allowlist in terms of canonical paths, such as `/usr/bin/ls`, rather than bare executable names. 3. Reject executables that: - resolve outside approved directories; - are symlinks to unapproved locations; - are writable by the current user, group, or untrusted users; - are not owned by an expected trusted account. 4. Return a validated executable path and parsed argument vector to the caller instead of returning only a Boolean decision for the original command string. 5. Require callers to execute the validated path directly with a non-shell API and an explicit sanitized environment. 6. Avoid time-of-check/time-of-use races. Where the execution architecture permits, open and validate the executable securely and execute the validated object rather than resolving the path again. 7. Add regression tests that place a fake allowlisted executable in a temporary directory at the front of `PATH` and verify that it is rejected. ]]>
