Back to skill

Security audit

Imessage Sender

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent image-sending purpose, but it can automatically transmit local files through Messages and contains unsafe AppleScript construction that could be abused.

Review before installing. Only use this with explicit recipient and file confirmation, and avoid sending sensitive files. The author should validate image files, restrict or confirm paths and recipients, pass AppleScript values as arguments instead of interpolating them, and clean up staged copies after sending.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/send.py:44
Finding
AppleScript Injection Through Unsanitized Recipient and File Path<![CDATA[ ## Vulnerability Details **File Location**: `scripts/send.py`, lines 44-57 **Vulnerability Type**: AppleScript injection leading to arbitrary command execution **Risk Level**: High ### Vulnerable Code ```python # Phone number format: +86XXXXXXXXXX formatted_recipient = recipient if not recipient.startswith('+'): if len(recipient) == 11: formatted_recipient = '+86' + recipient # Use POSIX file path format script = f''' tell application "Messages" activate send POSIX file "{send_path}" to participant "{formatted_recipient}" end tell ''' result = subprocess.run( ['osascript', '-e', script], capture_output=True, text=True ) ``` ### Technical Analysis The script dynamically constructs AppleScript source by directly interpolating `formatted_recipient` and `send_path` into quoted AppleScript strings. Neither value is escaped for the AppleScript grammar. The recipient is supplied directly through the command line. The destination filename is derived from the basename of the user-provided image path and can therefore also contain quotation marks or other AppleScript syntax on supported filesystems. Although `subprocess.run` uses an argument list rather than a shell command, this does not prevent the vulnerability. The generated string is intentionally passed to `osascript` as executable AppleScript source. An attacker can use a quotation mark to terminate one of the intended string literals, insert additional AppleScript statements, and neutralize the remainder of the generated statement. Injected AppleScript executes under the identity and permissions of the user running the skill. Subject to macOS privacy and Automation controls already granted to the invoking process, injected code could control applications, read accessible files, or invoke shell commands through AppleScript's `do shell script` functionality. ### Attack Path 1. An attacker ca ...[truncated 1327 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not interpolate untrusted values into executable AppleScript source. 1. Pass the recipient and path as separate `osascript` arguments. 2. Retrieve those values from an AppleScript `on run argv` handler so that they remain data rather than source code. 3. Validate recipients against a strict allowlist format, such as an international telephone-number pattern, and reject quotation marks, control characters, line breaks, and unexpected syntax. 4. Resolve and validate the source path before invoking Messages. 5. Avoid displaying raw interpreter errors if they could contain sensitive data. 6. Add regression tests using recipients and filenames containing quotes, backslashes, newlines, and AppleScript keywords. A safer invocation pattern is: ```python apple_script = r''' on run argv set attachmentPath to item 1 of argv set recipientAddress to item 2 of argv tell application "Messages" activate send POSIX file attachmentPath to participant recipientAddress end tell end run ''' result = subprocess.run( ["osascript", "-e", apple_script, str(send_path), formatted_recipient], capture_output=True, text=True, check=False, ) ``` Recipient validation should occur before this call, and only explicitly supported phone-number or account formats should be accepted. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/send.py:27
Finding
Arbitrary Local File Disclosure Through Missing Image and Path Validation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/send.py`, lines 27-53 **Vulnerability Type**: Unrestricted local file transmission **Risk Level**: High ### Vulnerable Code ```python # Ensure absolute path abs_path = os.path.abspath(image_path) # Copy to dedicated folder (avoid path issues) send_folder = Path.home() / "Pictures" / "openclaw-send" send_folder.mkdir(parents=True, exist_ok=True) # Generate new filename filename = f"send_{Path(abs_path).name}" send_path = send_folder / filename # Copy file import shutil shutil.copy2(abs_path, send_path) # Phone number format: +86XXXXXXXXXX formatted_recipient = recipient if not recipient.startswith('+'): if len(recipient) == 11: formatted_recipient = '+86' + recipient # Use POSIX file path format script = f''' tell application "Messages" activate send POSIX file "{send_path}" to participant "{formatted_recipient}" end tell ''' ``` ### Technical Analysis The skill is documented as an image-sending utility, but `image_path` is accepted without verifying that it refers to an image. The implementation does not validate: - The file's actual content or media type. - Its filename extension. - Whether it is a regular file. - Whether it is a symbolic link resolving to a sensitive file. - Whether its resolved path is within an approved image directory. - Whether the recipient is authorized to receive the selected file. `os.path.abspath` only converts the supplied value into an absolute path. It does not establish trust, restrict traversal, resolve authorization, or prove that the target is an image. `shutil.copy2` consequently copies any readable file to the staging directory, after which Messages sends that copied file to the supplied recipient. Because both the source path and recipient come from command-line arguments, a malicious or manipulated request can use the ...[truncated 1713 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Apply defense-in-depth controls before copying or sending a file: 1. Resolve the path with `Path.resolve(strict=True)` and enforce that it is under one or more explicitly approved image directories. 2. Reject symbolic links and require the source to be a regular file. 3. Validate actual image content with a trusted image decoder rather than relying only on the extension or reported MIME type. 4. Permit only an explicit set of image formats required by the skill. 5. Enforce a reasonable maximum file size to prevent accidental resource exhaustion. 6. Validate the recipient against an approved contact or require explicit user confirmation. 7. Before transmission, display the resolved source path, detected image type, file size, and normalized recipient. 8. Require confirmation for every send operation when sensitive local access is possible. 9. Remove the staged copy after transmission using a `finally` block, or use a securely managed temporary location with restrictive permissions. 10. Create the storage directory and configuration files with user-only permissions where practical. A secure path policy should resemble: ```python source = Path(image_path).expanduser() if source.is_symlink(): raise ValueError("Symbolic links are not permitted") source = source.resolve(strict=True) if not source.is_file(): raise ValueError("The source must be a regular file") approved_root = (Path.home() / "Pictures").resolve() if source != approved_root and approved_root not in source.parents: raise ValueError("The source must be inside the approved image directory") ``` This path validation must be combined with content-based image verification; directory and extension checks alone are insufficient. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (6)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill invokes shell commands and performs file-writing behavior but does not declare any tool scope such as permissions or allowed-tools. This creates a mismatch between what the skill can do and what reviewers or enforcement systems can constrain, increasing the risk of unauthorized command execution or unintended file modification.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
### Send Image

When user requests to send an image, automatically send via iMessage to the phone.

### Manual Commands
Confidence
93% confidence
Finding
The phrase 'automatically send' authorizes autonomous action that transmits user data through a messaging app without an explicit approval gate at send time. Because images are often sensitive, automatic dispatch increases the chance of accidental disclosure and makes prompt-injection or ambiguous requests more dangerous in this skill context.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger 'When user requests to send an image, automatically send via iMessage to the phone' is broad and can activate on loosely phrased user requests without confirming the recipient, image path, or intent. In a messaging context, overly permissive activation can lead to accidental exfiltration of private images to the configured phone number.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill omits a clear warning that using it will transmit an image to a phone number via iMessage and copy the file into ~/Pictures/openclaw-send/. Missing disclosure of these side effects undermines informed consent and may cause users to expose sensitive data or leave unintended local copies behind.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The code automatically assumes a China locale by prepending +86 to any 11-digit recipient number. This imposes a specific regional convention without offering the user a choice or documenting that the skill is intended only for a China-specific context.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
end tell
    '''
    
    result = subprocess.run(
        ['osascript', '-e', script],
        capture_output=True,
        text=True
Confidence
95% confidence
Finding
The subprocess call itself is not using a shell, but it passes attacker-controlled data into an AppleScript string executed by osascript. Both recipient and send_path are interpolated without escaping, so crafted input containing AppleScript metacharacters such as quotes can break out of the intended string and inject arbitrary AppleScript commands, potentially triggering arbitrary local actions on the Mac through scriptable applications.

Static analysis

No suspicious patterns detected.