T09 · Insecure Skill Coding Practices
- Location
src/bot/android/tiktok_android_bot.py:99- Finding
Android Shell Command Injection Through Unsanitized Newline Characters
- Content
View full analysis
Vulnerability Details
File Location:
src/bot/android/tiktok_android_bot.py:99-119
Vulnerability Type: Android shell command injection
Risk Level: HighVulnerable Code
python def _type_text(self, text: str): """Type text using ADB input. Args: text: Text to type (will escape special characters) """ # Remove emojis and special characters that cause issues # Keep only alphanumeric, spaces, and basic punctuation import re # Remove emojis text_clean = re.sub(r'[^\w\s\.,!?\'-]', '', text, flags=re.UNICODE) # Escape special characters for shell escaped = text_clean.replace(" ", "%s").replace("'", "").replace('"', '') if not escaped: log.warning(f"[Android Bot] Text became empty after cleaning: {text}") return self._adb_shell(f"input text {escaped}")The resulting command is executed through the following Android shell sink at
src/bot/android/tiktok_android_bot.py:46-63:python def _adb_shell(self, command: str, timeout: int = 10) -> str: """Execute ADB shell command.""" try: result = subprocess.run( ["adb", "-s", self.device_id, "shell", command], capture_output=True, text=True, timeout=timeout ) return result.stdout.strip()Technical Analysis
The regular expression permits every character matched by
\s, including carriage returns and newline characters. The subsequent escaping logic replaces only literal spaces and removes quotes; it does not reject control characters.The sanitized value is concatenated into a command string passed to
adb shell. A newline is interpreted by the Android shell as a command separator. Consequently, text originating from a search topic, a configured static comment, or an AI-generated comment can terminate the intendedinput textcommand and introduce another Android command.Using a
subprocess.run()argument list protects the ...[truncated 1407 chars]- Remediation
View remediation
Remediation Suggestions
-
Reject all control characters, especially
\r,\n, tabs, null bytes, and other Unicode separators. -
Replace
\swith an explicit literal-space character in the allowlist:python text_clean = re.sub(r"[^A-Za-z0-9 .,!?_-]", "", text) -
Enforce a reasonable maximum text length before passing it to ADB.
-
Prefer an Android input mechanism that does not construct shell command strings, such as a dedicated ADB keyboard or a UI automation API.
-
If
adb shell input textmust be used, validate the final encoded value against a strict pattern before execution:python if not re.fullmatch(r"[A-Za-z0-9%._,!?-]+", escaped): raise ValueError("Unsafe text for ADB input") -
Treat AI-generated text as untrusted input and apply the same validation regardless of provider.
-
Add regression tests covering newlines, carriage returns, tabs, shell metacharacters, and Unicode whitespace.
-
