Back to skill

Security audit

macOS CLT Offline Install

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for offline macOS Command Line Tools installation, but its generated installer uses administrator privileges after a weak signature check.

Review the generated install script before running it, download packages only from Apple catalog URLs, keep the package directory private, and independently confirm the package signer is Apple Software or Software Signing before entering an administrator password.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/make_install_sh.sh:19
Finding

Insufficient Package Publisher Verification Before Privileged Installation

Content
View full analysis

Vulnerability Details

File Location: scripts/make_install_sh.sh, lines 19–25 and 31–33
Vulnerability Type: Insufficient package-signature validation
Risk Level: Medium

Vulnerable Code

bash
echo "==> 校验 Apple 官方签名..."
for p in "$MAIN_PKG" ${SDK_PKGS[*]}; do
  [ -f "\$DIR/\$p" ] && pkgutil --check-signature "\$DIR/\$p" | grep -q "signed" || { echo "签名校验失败: \$p"; exit 1; }
done

echo "==> 安装主包 (需要输入开机密码)..."
sudo installer -pkg "\$DIR/$MAIN_PKG" -target /

echo "==> 安装 SDK 支持包..."

The generated script subsequently installs the optional SDK packages:

bash
for p in "${SDK_PKGS[@]}"; do
  [ -f "$PKG_DIR/$p" ] && echo "sudo installer -pkg \"\$DIR/$p\" -target / || echo \"跳过 \$p\"" >> "$OUT"
done

Technical Analysis

The generated installation script checks whether pkgutil --check-signature output contains the generic substring signed. It does not verify that the package was signed by Apple, validate the expected Apple certificate chain, or bind each fixed package name to trusted catalog metadata.

Consequently, a substituted package signed by an unrelated but valid signing identity may satisfy the check. The script then supplies that package to macOS installer under sudo, allowing package installation scripts and payload actions to run with elevated privileges.

The documentation and generated status message characterize this as verification of an official Apple signature, but the implemented test establishes only a weaker property: that the output includes the word signed.

Attack Path

  1. The legitimate packages are placed in the user-writable download directory, normally ~/Downloads/clt-install.
  2. An attacker who can modify that directory replaces one of the expected fixed-name package files with a malicious package carrying some otherwise valid signature.
  3. The user launches the generated install-clt.sh script.
  4. pkgutil --check-signature emits ...[truncated 1032 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace the generic substring check with strict validation of the expected Apple signing chain. Capture the complete pkgutil --check-signature output and require the precise Apple package-signing identity and certificate authorities expected for CLT packages.
  2. Fail closed if signature output is missing, malformed, ambiguous, expired, revoked, or associated with any non-Apple identity.
  3. Verify each downloaded package against trusted digest metadata from the authenticated Apple software catalog where such metadata is available.
  4. Allow only an explicit list of expected package filenames and reject symbolic links, unexpected file types, duplicate packages, or additional package files.
  5. Store downloads in a newly created directory with restrictive permissions and verify directory ownership and permissions before elevating privileges.
  6. Revalidate every package immediately before its corresponding sudo installer invocation to reduce the time-of-check/time-of-use window.
  7. Abort the entire installation if any required package fails validation. Do not continue after an SDK package installation or validation error unless that package is explicitly documented and securely handled as optional.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill instructs the agent to use both network access and shell commands, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates a least-privilege gap: an orchestrator may grant broader capabilities than necessary, and users or security controls cannot easily tell in advance that the skill will perform downloads and command execution.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

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.

Content

Scanner excerpt · scripts/find_clt_packages.py (reported line 10)May include surrounding context.

python
输出: 每行一个产品 (PostDate | 产品Key | 主包URL),加 --all 列出全部历史版本。
"""
import argparse
import plistlib
import re
import subprocess
import sys

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

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.

Content

Scanner excerpt · scripts/find_clt_packages.py (reported line 53)May include surrounding context.

python
输出: 每行一个产品 (PostDate | 产品Key | 主包URL),加 --all 列出全部历史版本。
"""
import argparse
import plistlib
import re
import subprocess
import sys

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/find_clt_packages.py (reported line 28)May include surrounding context.

python
def fetch(url: str) -> bytes:
    """优先走 shell 环境(可能带代理),失败则回退 urllib。"""
    try:
        r = subprocess.run(
            ["curl", "-sL", "--retry", "3", "--connect-timeout", "15", url],
            capture_output=True, timeout=180,
        )

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/make_install_sh.sh (reported line 26)May include surrounding context.

sh
done

echo "==> 安装主包 (需要输入开机密码)..."
sudo installer -pkg "\$DIR/$MAIN_PKG" -target /

echo "==> 安装 SDK 支持包..."
EOF

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/make_install_sh.sh (reported line 32)May include surrounding context.

sh
done

echo "==> 安装主包 (需要输入开机密码)..."
sudo installer -pkg "\$DIR/$MAIN_PKG" -target /

echo "==> 安装 SDK 支持包..."
EOF

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/make_install_sh.sh (reported line 37)May include surrounding context.

sh
done

echo "==> 安装主包 (需要输入开机密码)..."
sudo installer -pkg "\$DIR/$MAIN_PKG" -target /

echo "==> 安装 SDK 支持包..."
EOF