T09 · Insecure Skill Coding Practices
- Location
scripts/call.sh:111- Finding
AppleScript Injection Through an Untrusted Contact Query
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill does what it advertises at a high level, but it asks for broad UI automation authority and includes unsafe contact and notification handling that users should review before installing.
Install only if you are comfortable granting persistent macOS Accessibility authority to a generic NodeRunner.app and allowing the skill to place real FaceTime calls. Review or remove the contact-search and notification-clearing scripts, require explicit confirmation before every call, and revoke Accessibility access when no longer needed.
scripts/call.sh:111AppleScript Injection Through an Untrusted Contact Query
scripts/call.sh:40Unverified Notification Button Is Clicked Through Fixed UI Paths
scripts/setup.sh:13Generic Node Launcher Is Granted Excessive Accessibility Authority
A second mismatch indicates the skill may clear or inspect Notification Center state and manage notifications in ways not clearly tied to call placement. Hidden UI automation against system notifications can interfere with other apps, obscure alerts, or be repurposed for broader desktop manipulation, which is materially more dangerous than a simple calling tool.
A second mismatch indicates the skill may clear or inspect Notification Center state and manage notifications in ways not clearly tied to call placement. Hidden UI automation against system notifications can interfere with other apps, obscure alerts, or be repurposed for broader desktop manipulation, which is materially more dangerous than a simple calling tool.
This script performs global Notification Center clearing, which is materially broader than the stated purpose of placing FaceTime calls. Clearing notifications can hide security prompts, messages, MFA codes, alerts, or forensic evidence of other activity, making the behavior dangerous even if framed as convenience automation. In the context of a calling skill, this scope mismatch increases suspicion because the notification manipulation is not necessary to initiate or manage a call.
The skill advertises and demonstrates shell execution but does not declare any explicit tool scope such as allowed-tools or permissions. That creates an authorization ambiguity where an agent or reviewer may not realize the skill requires command execution, increasing the chance of unintended command use. In this context, shell access is especially sensitive because it can launch calls, run setup scripts, and interact with accessibility-enabled automation.
The description does not prominently warn that the skill can place real calls, access privacy-sensitive contact information, and use accessibility/UI automation. Without a clear warning, users may invoke it without understanding that it can contact real people and manipulate system UI, increasing privacy and safety risks.
The trigger phrases are broad enough that ordinary conversation like 'Call John' could cause the agent to place a real external call. Because calls are privacy-sensitive and externally visible, ambiguous natural-language activation increases the risk of accidental invocation and unintended contact with third parties.
The find-contact mode enumerates names, phone numbers, and email addresses from the user's Contacts database and prints them to output, which expands the skill from call placement into bulk disclosure of private address-book data. In an agent setting, this can expose sensitive personal information to logs, downstream tools, or an untrusted requester without a clear need tied to placing a FaceTime call.
The contact-directory lookup capability is broader than the stated purpose of making FaceTime calls and auto-clicking notifications, creating unnecessary access to a separate sensitive data source. This increases attack surface because a caller can use the skill to query private contacts data even when no call needs to be placed.
The script accesses Contacts data in find-contact mode without any user-facing warning in the help text about privacy-sensitive access or disclosure of stored phone numbers and email addresses. In a delegated agent workflow, that lack of notice makes unintended data exposure more likely because users may invoke the skill expecting only call automation, not address-book enumeration.
Forcefully killing NotificationCenter disrupts a core OS component and can dismiss or suppress active notifications unrelated to FaceTime. This can cause loss of user visibility into important security or system events and is not justified by the stated auto-call purpose, especially since it affects the entire desktop environment rather than only FaceTime UI state.
The setup script creates a generic wrapper app and explicitly instructs the user to grant it Accessibility permissions, which is a powerful UI-automation capability far broader than a narrowly scoped FaceTime helper. Because the app is a generic Node launcher rather than a dedicated signed binary limited to this skill, any Node-based code later run through it could inherit the trusted Accessibility context and control the user interface outside the stated purpose.
Provisioning a generic NodeRunner.app and asking the user to trust it with Accessibility privileges creates an overly broad execution surface. Accessibility on macOS can be abused to click dialogs, interact with other applications, and perform actions on the user's behalf, so granting it to a reusable Node wrapper exceeds what is justified for a FaceTime auto-call skill.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
EOF
chmod +x ~/Applications/NodeRunner.app/Contents/MacOS/NodeRunner
cat > ~/Applications/NodeRunner.app/Contents/Info.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
EOF
chmod +x ~/Applications/NodeRunner.app/Contents/MacOS/NodeRunner
cat > ~/Applications/NodeRunner.app/Contents/Info.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
EOF
chmod +x ~/Applications/NodeRunner.app/Contents/MacOS/NodeRunner
cat > ~/Applications/NodeRunner.app/Contents/Info.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
EOF
chmod +x ~/Applications/NodeRunner.app/Contents/MacOS/NodeRunner
cat > ~/Applications/NodeRunner.app/Contents/Info.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
cat > ~/Applications/NodeRunner.app/Contents/Info.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
No suspicious patterns detected.