Back to skill

Security audit

Mac Dev Staging

Security checks for vulnerabilities and agentic risk

Overview

This looks like a legitimate Mac staging helper, but it should be reviewed because it enables remote access, installs mutable global tooling, and generates privileged Apache config from weakly validated inputs.

Install only if you are comfortable letting the skill change your Mac's local server posture. Review Remote Login before enabling it, keep SSH/SFTP limited to trusted users and networks, avoid untrusted input to the vhost renderer, and consider pinning npm tooling or installing it project-locally.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Warning
Location
scripts/bootstrap-npm-tooling.sh:15
Finding
Unpinned Global npm Package Installation Creates a Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `scripts/bootstrap-npm-tooling.sh:15-27` **Vulnerability Type**: Unpinned third-party dependencies installed globally **Risk Level**: Medium ### Vulnerable Code ```bash prefix="$(npm prefix -g)" if [ ! -w "$prefix" ]; then prefix="$HOME/.local" mkdir -p "$prefix" npm config set prefix "$prefix" >/dev/null fi npm install -g browser-sync concurrently npm-check-updates vite echo echo "npm global prefix: $(npm prefix -g)" echo "Installed tooling:" npm list -g --depth=0 | egrep 'browser-sync|concurrently|npm-check-updates|vite' || true ``` ### Technical Analysis The script installs four packages from the npm registry without specifying exact versions, using a lockfile, or verifying package integrity. Consequently, the code installed by the script is determined by mutable npm registry state at execution time rather than by the audited Skill contents. npm packages can execute lifecycle scripts during installation. If one of the named packages or any transitive dependency is compromised, the malicious release can execute code with the privileges of the user running this bootstrap script. Global installation also makes the affected tools available outside this project and increases the duration and scope of exposure. The script attempts to use a writable global prefix and otherwise changes the user's npm global prefix to `$HOME/.local`. Under the documented workflow, compromise would ordinarily obtain the invoking user's privileges rather than root privileges. The impact would be greater if an operator independently ran the script through `sudo`, although the project does not instruct the operator to do so. ### Attack Path 1. An attacker compromises one of the named npm packages, a transitive dependency, or its publishing account. 2. The attacker publishes a malicious release or dependency update containing an install-time lifecycle script or malicious runtime behavior. 3. An operator runs `scripts/b ...[truncated 1050 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct dependency to an exact, reviewed version rather than relying on npm's current latest release: ```bash npm install --save-exact \ browser-sync@REVIEWED_VERSION \ concurrently@REVIEWED_VERSION \ npm-check-updates@REVIEWED_VERSION \ vite@REVIEWED_VERSION ``` 2. Install tooling in a project-local package rather than globally. 3. Commit `package.json` and `package-lock.json`, and use `npm ci` so dependency resolution is reproducible. 4. Review and update the lockfile through a controlled dependency-update process. 5. Use `npm ci --ignore-scripts` when lifecycle scripts are unnecessary. If lifecycle scripts are required, explicitly review the packages that use them. 6. Run package provenance, integrity, and vulnerability checks in CI before accepting dependency updates. 7. Avoid running npm bootstrap operations through `sudo`. 8. Do not change the user's persistent global npm configuration merely to support this project; use a project-local tool directory or invoke tools through package scripts. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/render-vhost.sh:16
Finding
Apache Configuration Injection in Virtual Host Renderer<![CDATA[ ## Vulnerability Details **File Location**: `scripts/render-vhost.sh:16-46` **Vulnerability Type**: Apache configuration injection through insufficient input validation **Risk Level**: Medium ### Vulnerable Code ```bash while [[ $# -gt 0 ]]; do case "$1" in --server-name) SERVER_NAME="${2:-}"; shift 2 ;; --docroot) DOCROOT="${2:-}"; shift 2 ;; --error-log) ERROR_LOG="${2:-}"; shift 2 ;; --access-log) ACCESS_LOG="${2:-}"; shift 2 ;; -h|--help) usage; exit 0 ;; *) echo "Unknown argument: $1" >&2; usage; exit 1 ;; esac done [[ -n "$SERVER_NAME" && -n "$DOCROOT" ]] || { usage; exit 1; } [[ "$DOCROOT" = /* ]] || { echo "docroot must be absolute" >&2; exit 1; } ERROR_LOG="${ERROR_LOG:-/private/var/log/apache2/${SERVER_NAME}_error.log}" ACCESS_LOG="${ACCESS_LOG:-/private/var/log/apache2/${SERVER_NAME}_access.log}" cat <<EOF <VirtualHost *:80> ServerName ${SERVER_NAME} DocumentRoot "${DOCROOT}" <Directory "${DOCROOT}"> AllowOverride All Options Indexes FollowSymLinks Require all granted </Directory> ErrorLog "${ERROR_LOG}" CustomLog "${ACCESS_LOG}" common </VirtualHost> EOF ``` ### Technical Analysis All four command-line values are interpolated directly into Apache configuration syntax. The script only checks that `DOCROOT` starts with `/`; it does not validate the hostname syntax or reject line breaks, carriage returns, quotation marks, control characters, or Apache directive delimiters. Shell quoting protects the script from ordinary shell command injection, but it does not make the resulting Apache configuration safe. A value containing a newline can terminate the intended directive and introduce another directive. Values placed inside double quotes can also contain a quote and escape their intended Apache argument context. `SERVER_NAME` is especially exposed because it is emitted without Apache quoting and is also incorporated into default log paths. `DOCROOT`, `ERROR ...[truncated 2208 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate `SERVER_NAME` against a strict hostname allowlist. For example, permit only ASCII letters, digits, dots, and hyphens, while rejecting leading or trailing separators and empty labels. 2. Reject carriage returns, line feeds, NUL bytes, control characters, double quotes, backslashes, and Apache structural characters in every rendered value. 3. Canonicalize `DOCROOT` with an appropriate platform utility and verify that it: - Is an absolute path. - Exists and is a directory when required. - Falls under an explicitly approved development root. - Does not resolve through symlinks to an unintended sensitive directory. 4. Apply equivalent path validation to custom access-log and error-log paths. Prefer generating those paths internally instead of accepting arbitrary values. 5. Fail closed when a value cannot be represented safely in Apache configuration; do not attempt ad hoc escaping without accounting for Apache's configuration grammar. 6. Write generated configuration to a temporary unprivileged file, run `apachectl configtest` against the proposed configuration, and present a clear diff before privileged installation. 7. Keep privileged installation as a distinct, explicit operator step and warn that renderer input must not originate from untrusted project metadata. 8. Harden the generated virtual-host defaults where possible: ```apache AllowOverride None Options -Indexes -FollowSymLinks ``` Enable overrides, indexing, or symlink following only when a specific application requires them. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The declared purpose is local macOS PHP/MariaDB staging, but the skill also introduces a local gateway/controller surface and references coexistence with a main gateway. That mismatch widens the operational scope beyond simple web-stack setup, which can mislead reviewers and users about the networking and control-plane exposure being introduced.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill clearly instructs execution of shell commands and describes scripts that can render configs, install packages, and write receipts, yet it declares no explicit tool scope or allowed-tools boundary. In an agentic environment, this creates an overbroad execution surface where a caller may grant file-write and shell capabilities implicitly, increasing the risk of unintended system changes or abuse.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
If Remote Login is off, enable it with macOS settings or:

```bash
sudo systemsetup -setremotelogin on
```

Recommended pattern:
Confidence
79% confidence
Finding
Enabling Remote Login with sudo turns on SSH/SFTP access for the host, expanding the attack surface beyond local-only staging. Even though the skill advises reading additional guidance, presenting a direct command to enable remote access can lead to unnecessary exposure if users enable it without hardening authentication, user access, and network restrictions.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This markdown file instructs the user to enable Remote Login, including a sudo command, which changes the system's remote-access posture. Although later security notes recommend limiting exposure, the enablement section itself does not clearly warn the user before the potentially security-sensitive change is performed.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
CLI path:

```bash
sudo systemsetup -setremotelogin on
```

## Verification
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
CLI path:

```bash
sudo systemsetup -setremotelogin on
```

## Verification
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
apache)
      case "$action" in
        start|stop|restart)
          sudo apachectl "$action"
          ;;
        *)
          echo "unsupported apache action: $action" >&2
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Static analysis

No suspicious patterns detected.