T09 · Insecure Skill Coding Practices
- Location
wechat-send.py:50- Finding
AppleScript Injection Through Crafted File Paths
- Content
View full analysis
Vulnerability Details
File Location:
wechat-send.py, lines 50–64
Vulnerability Type: AppleScript injection leading to arbitrary command execution
Risk Level: Highpython def copy_file_in_finder(file_path): """在 Finder 中选中文件并复制(Cmd+C)""" abs_path = os.path.abspath(file_path) # 使用 POSIX file 语法,更好地处理特殊字符 script = f''' tell application "Finder" activate select POSIX file "{abs_path}" delay 0.3 tell application "System Events" keystroke "c" using command down end tell delay 0.3 end tell ''' try: subprocess.run(['osascript', '-e', script], check=True, timeout=10)Technical Analysis
The file path is interpolated directly into executable AppleScript source without escaping quotation marks, backslashes, or newline characters. macOS filenames can contain characters capable of terminating the AppleScript string literal.
Although
subprocess.run()uses an argument array and therefore avoids shell parsing at the Python process boundary, this does not prevent injection into the AppleScript language itself. A crafted existing filename can close thePOSIX filestring and append additional AppleScript statements. AppleScript supports commands such asdo shell script, so successful injection can result in arbitrary local command execution.The preceding
is_file_path()validation only confirms that the supplied value refers to an existing file. It does not make the filename safe for inclusion in AppleScript source.Attack Path
- An attacker creates, supplies, or persuades the user to create a file whose name contains AppleScript syntax, including a string terminator and injected statement.
- The user invokes the Skill with the crafted file path as an item to send.
is_file_path()accepts the argument because the crafted path identifies an existing file.
...[truncated 796 chars]
- Remediation
View remediation
Remediation Suggestions
Do not concatenate file paths into AppleScript source. Pass the path as a separate
osascriptargument and retrieve it through anon run argvhandler so that it remains data:python script = ''' on run argv set targetPath to item 1 of argv tell application "Finder" activate select POSIX file targetPath delay 0.3 tell application "System Events" keystroke "c" using command down end tell delay 0.3 end tell end run ''' subprocess.run( ['osascript', '-e', script, '--', abs_path], check=True, timeout=10 )Additional hardening should include:
- Resolve and validate the path before invoking AppleScript.
- Reject unsupported file types or locations if the operational requirements permit allowlisting.
- Avoid implementing manual escaping when a parameterized argument channel is available.
- Add regression tests using filenames containing double quotes, backslashes, Unicode characters, and newline characters.
- Report AppleScript failures clearly rather than continuing with uncertain clipboard or UI state.
