Back to skill

Security audit

apple-notes-writer

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its Apple Notes automation purpose, but it needs review because it can read and change persistent Notes data through dynamically generated AppleScript with weak scoping and no confirmation guardrails.

Install only if you want an agent to control Apple Notes on your Mac. Confirm every create, read, list, folder-create, and update request yourself, avoid using it with sensitive Notes folders, and do not pass folder names, titles, note IDs, or content from untrusted sources until the AppleScript argument handling and confirmation behavior are improved.

Vulnerability Patterns
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (18)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# 构建并执行AppleScript
        script = self._build_applescript(title, content, folder, update_existing)
        
        result = subprocess.run(
            ['osascript', '-e', script],
            capture_output=True,
            text=True
Confidence
95% confidence
Finding
This subprocess call executes dynamically constructed AppleScript that embeds untrusted inputs such as title, body, folder, and account directly into script source. The custom escaping only handles backslashes and double quotes, which is insufficient for AppleScript context safety, creating a real script-injection risk that can lead to arbitrary AppleScript execution against local applications and user data.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
end try
end tell
'''
        result = subprocess.run(
            ['osascript', '-e', script],
            capture_output=True,
            text=True
Confidence
94% confidence
Finding
The read path also builds AppleScript from user-controlled folder/title values and executes it with osascript. Because these values are inserted into script text with incomplete escaping, an attacker may break script structure and execute unintended AppleScript, turning a simple read capability into broader local automation abuse.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
return noteNames as string
end tell
'''
        result = subprocess.run(
            ['osascript', '-e', script],
            capture_output=True,
            text=True
Confidence
93% confidence
Finding
Listing notes executes AppleScript built from the untrusted folder/account context. Although subprocess.run is invoked without a shell, the danger is not shell injection but injection into the AppleScript interpreter via the script string passed to osascript.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
end try
end tell
'''
        result = subprocess.run(
            ['osascript', '-e', script],
            capture_output=True,
            text=True
Confidence
95% confidence
Finding
The update_by_id path is particularly sensitive because it combines direct note mutation with dynamic AppleScript execution using attacker-controlled note_id and content. Successful injection here could both overwrite data and run arbitrary AppleScript actions under the user's permissions.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
end try
end tell
'''
        result = subprocess.run(
            ['osascript', '-e', script],
            capture_output=True,
            text=True
Confidence
93% confidence
Finding
This code executes AppleScript generated from title/folder/account values to retrieve note IDs. The same AppleScript injection issue applies, and exposing internal note IDs also facilitates later arbitrary note targeting if other mutation methods are available.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
end try
end tell
'''
        result = subprocess.run(
            ['osascript', '-e', script],
            capture_output=True,
            text=True
Confidence
94% confidence
Finding
Folder creation constructs AppleScript from untrusted folder names and executes it directly. An attacker who controls folder_name or account-related values may inject AppleScript statements, leading to arbitrary local automation actions beyond simple folder creation.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill advertises and documents shell execution (`osascript` via `subprocess.run`) and file reading (`--file content.md`, Python file I/O), but the metadata does not declare those permissions. Undeclared capabilities weaken review and consent boundaries, making it easier for a user or orchestrator to invoke filesystem and shell actions without clear disclosure.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared purpose focuses on writing formatted Apple Notes, but the documented behavior includes reading note contents, listing notes, creating folders, resolving IDs, and returning verification output. This mismatch is dangerous because users may authorize a write-only helper while the skill also exposes note discovery and content retrieval functions, expanding access to potentially sensitive personal data.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The skill is presented as a writer, but it also reads note contents, lists note titles, and exposes note IDs. This capability mismatch increases the chance that users or higher-level agents grant broader data access than expected, creating a privacy and overreach issue in the skill's effective permissions.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
Updating arbitrary notes by internal note ID is more powerful than the advertised note-writing behavior because it bypasses normal title/folder targeting and can directly modify existing data. In an agent setting, this hidden capability makes unauthorized tampering easier and reduces user visibility into what will be changed.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The trigger phrases are broad and can match ordinary conversation, making accidental invocation plausible. In an agent environment, that can cause unintended creation or modification of Apple Notes, which is a real integrity risk because the skill performs side effects on user data.

Vague Triggers

Medium
Confidence
86% confidence
Finding
The trigger phrases are broad and generic, so ordinary conversations about taking notes could unintentionally invoke a skill that performs AppleScript-based note creation or modification. In a system with automatic tool routing, this increases the chance of unintended side effects on the user's Notes data.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The workflow describes executing AppleScript to create or update notes, but the skill lacks a clear user-facing warning that it will automate Apple Notes and modify persistent local/iCloud data. Without that disclosure, users may not understand that this is not just formatting assistance but a system-automation action with lasting effects.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The write path can create or overwrite notes with no explicit warning, preview, or confirmation, especially when update_existing is enabled. In an agent environment this raises integrity risks because a mistaken prompt, malicious upstream input, or injected parameters can silently alter user data.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
Updating by note ID performs a direct overwrite with no confirmation and no human-readable targeting context. Because IDs are opaque, users cannot easily verify what will be modified, making accidental or unauthorized data tampering substantially more dangerous.

Unvalidated Output Injection

High
Category
Output Handling
Content
'''
    
    # 执行
    result = subprocess.run(['osascript', '-e', script], capture_output=True, text=True)
    
    if result.returncode == 0:
        return True, "成功"
Confidence
99% confidence
Finding
The code builds AppleScript by interpolating untrusted values such as title, content_html, and note_id directly into a script string and then passes it to osascript. Escaping only backslashes and double quotes is insufficient for AppleScript contexts, so crafted input can break out of the intended string and alter script behavior, leading to arbitrary AppleScript execution or unauthorized Notes actions.

Unvalidated Output Injection

High
Category
Output Handling
Content
end if
end tell
'''
result = subprocess.run(['osascript', '-e', script], capture_output=True, text=True)
note_id = result.stdout.strip()
```
Confidence
96% confidence
Finding
The search example executes dynamically constructed AppleScript via osascript and then trusts stdout as a note identifier without validation. In practice, untrusted search terms or malformed output could influence later control flow and enable unauthorized note targeting when that ID is reused in follow-on scripts.

Unvalidated Output Injection

High
Category
Output Handling
Content
return body of targetNote
end tell
'''
result = subprocess.run(['osascript', '-e', verify_script], capture_output=True, text=True)
print(result.stdout)
```
Confidence
98% confidence
Finding
The verification snippet interpolates note_id directly into AppleScript and executes it with osascript. If note_id is attacker-controlled or derived from untrusted output, it can alter the script and read arbitrary Notes content or perform unintended AppleScript actions, extending the impact beyond a simple verification step.

Static analysis

No suspicious patterns detected.