Back to skill

Security audit

Macos Spm App Packaging

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for macOS app packaging, but its scripts handle signing credentials and destructive cleanup in ways users should review before use.

Install only if you are comfortable reviewing and hardening the scripts before running them. Do not run the notarization script with real App Store Connect credentials until fixed /tmp key paths are replaced with private mktemp directories and restrictive permissions. Keep APP_NAME to a simple basename, treat version.env as trusted code unless parsing is changed, and understand that setup_dev_signing.sh creates a persistent signing identity in the login Keychain.

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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
assets/templates/sign-and-notarize.sh:16
Finding

App Store Connect Private Key Written to a Predictable Shared Temporary File

Content
View full analysis
/tmp/app-store-connect-key.p8 trap 'rm -f /tmp/app-store-connect-key.p8 /tmp/${APP_NAME}Notarize.zip' EXIT ``` The resulting file is subsequently used here: ```bash xcrun notarytool submit "/tmp/${APP_NAME}Notarize.zip" \ --key /tmp/app-store-connect-key.p8 \ --key-id "$APP_STORE_CONNECT_KEY_ID" \ --issuer "$APP_STORE_CONNECT_ISSUER_ID" \ --wait ``` ### Technical Analysis The script writes an App Store Connect API private key to the fixed path `/tmp/app-store-connect-key.p8`. Because ordinary shell redirection creates or truncates the destination while following symbolic links, an existing attacker-controlled path can redirect the secret into another user-writable file. A process able to observe the shared temporary directory may also attempt to read the key while it exists. The file permissions depend on the invoking process's `umask`; the script does not explicitly enforce owner-only permissions. Deleting the file through an EXIT trap limits how long it remains present but does not protect it during script execution or prevent symlink attacks before creation. ### Attack Path 1. An attacker with local access predicts the fixed `/tmp/app-store-connect-key.p8` pathname. 2. The attacker monitors the path or prepares it as a symbolic link to an attacker-readable or victim-owned destination. 3. A release operator runs `sign-and-notarize.sh` with a valid App Store Connect private key in the environment. 4. Shell redirection writes the private key through the predictable path. 5. The attacker reads the exposed credential or causes an unintended file to be overwritten. 6. Cleanup occurs only after the credential has already been exposed or the ...[truncated 528 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
assets/templates/setup_dev_signing.sh:36
Finding

Development Signing Keys Exposed Through Predictable Temporary Paths

Content
View full analysis
/dev/null openssl pkcs12 -export -out /tmp/dev.p12 \ -inkey /tmp/dev.key -in /tmp/dev.crt \ -passout pass: 2>/dev/null security import /tmp/dev.p12 -k ~/Library/Keychains/login.keychain-db \ -T /usr/bin/codesign -T /usr/bin/security rm -f /tmp/dev.{key,crt,p12} ``` ### Technical Analysis The generated RSA private key is explicitly unencrypted because `openssl req` uses `-nodes`. The script then exports the identity to a PKCS#12 file with an empty password. Both sensitive artifacts use fixed filenames in the shared `/tmp` directory. Existing files and symbolic links are not rejected. Consequently, another local process may predict and monitor these paths, redirect output through a symbolic link, substitute generated material, or interfere with concurrent execution. Although a temporary configuration file is protected by an EXIT trap, the key, certificate, and PKCS#12 files are only removed by a command reached after successful Keychain import. An interruption or earlier command failure can leave sensitive material behind. Importing a stable development identity into the login Keychain is consistent with the declared signing workflow. The vulnerability is the insecure staging of the identity, not the legitimate Keychain import itself. ### Attack Path 1. An attacker predicts `/tmp/dev.key`, `/tmp/dev.crt`, and `/tmp/dev.p12`. 2. The attacker monitors one of these paths or creates an applicable symbolic link before the setup script runs. 3. The user invokes `setup_dev_signing.sh`. 4. OpenSSL writes an unencrypted private key and a passwordless PKCS#12 bundle to the pre ...[truncated 814 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
assets/templates/package_app.sh:8
Finding

Unvalidated Application Name Can Redirect Recursive Deletion Outside the Project

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
assets/templates/compile_and_run.sh:6
Finding

Application Name Is Interpreted as a Process-Matching Regular Expression

Content
View full analysis
Killing existing ${APP_NAME} instances" pkill -f "${APP_PROCESS_PATTERN}" 2>/dev/null || true pkill -f "${DEBUG_PROCESS_PATTERN}" 2>/dev/null || true pkill -f "${RELEASE_PROCESS_PATTERN}" 2>/dev/null || true pkill -x "${APP_NAME}" 2>/dev/null || true ``` From `assets/templates/launch.sh`: ```bash APP_NAME=${APP_NAME:-MyApp} APP_PATH="$PROJECT_ROOT/${APP_NAME}.app" echo "==> Killing existing ${APP_NAME} instances" pkill -x "$APP_NAME" || pkill -f "${APP_NAME}.app" || true ``` ### Technical Analysis `pkill` treats its pattern argument as a regular expression. Quoting the shell variable prevents shell expansion but does not convert the pattern into a literal string. An application name containing metacharacters such as `.`, `*`, `[`, `]`, `^`, or `$` can broaden the match. Because `APP_NAME` is environment-controlled and not validated, a malicious value such as a broad regular expression can cause `pkill` to select unrelated processes. The `-f` variants match against full command lines, increasing the potential match scope. ### Attack Path 1. An attacker controls or influences `APP_NAME` in the environment used by a developer. 2. The attacker supplies a broad regular expression rather than a literal application name. 3. The developer invokes `compile_and_run.sh` or `launch.sh`. 4. The script passes the expression to one or more `pk ...[truncated 475 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
assets/templates/package_app.sh:15
Finding

Version Configuration File Is Executed as Arbitrary Shell Code

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script writes an unencrypted private key, certificate, and PKCS#12 bundle to fixed, predictable paths under /tmp. On multi-user systems or in the presence of symlink/race attacks, another local process could read, replace, or redirect these files before cleanup, resulting in disclosure or misuse of the signing key material.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script writes the App Store Connect private key to a fixed, predictable path in /tmp, which is a shared world-accessible namespace on multi-user systems. Even though a cleanup trap is present, another local process could race to read, replace, or symlink that file before use or deletion, risking credential exposure or misuse.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

The script executes '$ROOT/version.env' with 'source', which runs arbitrary shell code from that file rather than just parsing key/value data. If an attacker can modify version.env in the repository or workspace, packaging will execute attacker-controlled commands in the user's shell context, potentially accessing signing material or altering the build output.

Content

Scanner excerpt · assets/templates/package_app.sh (reported line 15)May include surrounding context.

sh
SIGNING_MODE=${SIGNING_MODE:-}
APP_IDENTITY=${APP_IDENTITY:-}

if [[ -f "$ROOT/version.env" ]]; then
  source "$ROOT/version.env"
else
  MARKETING_VERSION=${MARKETING_VERSION:-0.1.0}

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

This finding refers to the same unsafe pattern: loading version.env via 'source' causes shell execution of file contents. In a packaging skill, this is more dangerous because the script may run in environments with developer credentials, signing identities, and access to release artifacts.

Content

Scanner excerpt · assets/templates/package_app.sh (reported line 16)May include surrounding context.

sh
APP_IDENTITY=${APP_IDENTITY:-}

if [[ -f "$ROOT/version.env" ]]; then
  source "$ROOT/version.env"
else
  MARKETING_VERSION=${MARKETING_VERSION:-0.1.0}
  BUILD_NUMBER=${BUILD_NUMBER:-1}

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

The EXIT trap embeds ${APP_NAME} inside a single-quoted command string that will be expanded when the trap executes. Because APP_NAME is environment-controlled and unvalidated, shell metacharacters or command substitutions in APP_NAME could alter the trap command and trigger unintended command execution during cleanup.

Content

Scanner excerpt · assets/templates/sign-and-notarize.sh (reported line 17)May include surrounding context.

sh
fi

echo "$APP_STORE_CONNECT_API_KEY_P8" | sed 's/\\n/\n/g' > /tmp/app-store-connect-key.p8
trap 'rm -f /tmp/app-store-connect-key.p8 /tmp/${APP_NAME}Notarize.zip' EXIT

ARCHES_VALUE=${ARCHES:-"arm64 x86_64"}
ARCH_LIST=( ${ARCHES_VALUE} )

Static analysis

No suspicious patterns detected.