T09 · Insecure Skill Coding Practices
- Location
- references/infrastructure-chaos.md:236
- Finding
- Root Command Injection Through Unsanitized Domain Input<![CDATA[ ## Vulnerability Details **File Location**: `references/infrastructure-chaos.md:236-260` **Vulnerability Type**: OS command injection across a root privilege boundary **Risk Level**: High ### Vulnerable Code ```python class DNSChaos: @staticmethod @contextmanager def block_domain(domain: str, duration_seconds: int = 60): """Block DNS resolution for domain by pointing to localhost.""" try: # Add entry to /etc/hosts subprocess.run([ 'sudo', 'sh', '-c', f'echo "127.0.0.1 {domain}" >> /etc/hosts' ], check=True) print(f"Blocked DNS for {domain}") yield finally: # Wait for duration time.sleep(duration_seconds) # Remove entry from /etc/hosts subprocess.run([ 'sudo', 'sed', '-i', f'/127.0.0.1 {domain}/d', '/etc/hosts' ], check=True) print(f"Restored DNS for {domain}") ``` ### Technical Analysis The caller-controlled `domain` value is interpolated into a command passed to `sudo sh -c`. Because the shell interprets the resulting string, command substitutions and other shell syntax embedded in `domain` are evaluated with root privileges. Double quotation marks do not prevent command substitution. For example, a domain containing `$(command)` can cause `command` to execute before the generated text is appended to `/etc/hosts`. The cleanup operation also inserts the unescaped domain into a `sed` expression. Although that call does not use a shell, specially crafted regular-expression or delimiter content can alter which lines are removed. The root shell exceeds the minimum privilege necessary for generating chaos-test configuration and creates a direct privilege-escalation path when the domain is not fully trusted. ### Attack Path 1. An attacker influences the domain supplied to `DNSChaos.block_domain()`. 2 ...[truncated 635 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Do not invoke `sh -c` with caller-controlled content. - Validate domains with a strict parser and allow only valid DNS labels. - Reject whitespace, shell metacharacters, control characters, slashes, and newline characters. - Perform an atomic, direct file update rather than constructing a shell command. - Add a unique fixed marker to the inserted line and remove only that exact marker during cleanup. - Run the experiment inside an isolated container or network namespace instead of modifying the host-wide `/etc/hosts`. - If elevation is unavoidable, expose a narrowly scoped privileged helper that accepts validated structured input rather than granting general root-shell access. - Preserve the original file, restore it in a `finally` block, and verify the restored state. ]]>
