Back to skill

Security audit

MLX Audio Server

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for a local Mac STT/TTS server, but it automatically installs mutable third-party Homebrew code and starts a persistent background API service with limited scoping and security guidance.

Review before installing. This skill may leave a Mac background audio API running after setup, and it installs the server from a third-party Homebrew tap that can change after review. Prefer localhost-only use, avoid sending sensitive audio or text unless you trust the local server, inspect the Homebrew formula first, and know how to stop or uninstall the service before enabling it.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (3)

T08 · Insecure Dependencies

Error
Location
install.sh:5
Finding
Unpinned Third-Party Homebrew Formula Creates a Mutable Supply-Chain Execution Path## Vulnerability Details **File Location**: `install.sh`, lines 5-13 **Vulnerability Type**: Unverified and unpinned third-party dependency installation **Risk Level**: High ### Vulnerable Code ```bash brew update # use brew to install deps if not exists command -v ffmpeg || brew install ffmpeg command -v jq || brew install jq # install formula from tap: # https://github.com/guoqiao/homebrew-tap/blob/main/Formula/mlx-audio-server.rb brew install guoqiao/tap/mlx-audio-server || true ``` ### Technical Analysis The installer updates Homebrew metadata and installs `mlx-audio-server` from the mutable third-party tap `guoqiao/tap`. The project does not pin the formula to a reviewed commit or version and does not independently verify the formula, downloaded resources, or expected checksums. A Homebrew formula may execute installation logic and install executable resources. Consequently, the effective code installed by this script can change after the audited Skill package has been published. Compromise of the tap repository, its maintainer account, or an upstream resource referenced by the formula could turn the documented installation command into an arbitrary-code execution channel. The `|| true` suffix also suppresses installation failure. This can conceal dependency problems and allow execution to continue with an unexpected, stale, or partially installed package. ### Attack Path 1. An attacker compromises or gains update access to the third-party Homebrew tap or one of the formula's mutable upstream resources. 2. The attacker modifies the formula or referenced package to include malicious installation or runtime behavior. 3. A user follows the documented instructions and executes `install.sh`. 4. `brew update` obtains current package metadata, and `brew install guoqiao/tap/mlx-audio-server` retrieves the attacker's modified package. 5. Homebrew executes the malicious installation logic under the privileges of ...[truncated 737 chars]
Remediation
## Remediation Suggestions - Pin `mlx-audio-server` and all significant resources to reviewed, immutable versions or commits. - Verify downloaded artifacts using cryptographic hashes maintained in a trusted part of this project. - Audit and vendor the Homebrew formula where practical instead of relying on a mutable personal tap. - Avoid unconditional `brew update` during installation; document a tested Homebrew state or update dependencies through an explicit user-controlled step. - Remove `|| true` from security-relevant installation commands so failures are visible and abort installation. - Display the formula source, version, and expected checksums before installation. - Consider distributing a signed release and verifying its signature before installing or starting the service.

T06 · System Persistence

Warning
Location
install.sh:11
Finding
Installer Registers a Cross-Session Homebrew Service Without Separate Consent## Vulnerability Details **File Location**: `install.sh`, lines 11-16 **Vulnerability Type**: Persistent user-level service installation **Risk Level**: Medium ### Vulnerable Code ```bash # install formula from tap: # https://github.com/guoqiao/homebrew-tap/blob/main/Formula/mlx-audio-server.rb brew install guoqiao/tap/mlx-audio-server || true # (re)start brew service brew services restart mlx-audio-server || true ``` ### Technical Analysis The installation script automatically invokes `brew services restart`, which registers or restarts the installed server as a macOS background service. Homebrew services on macOS normally use LaunchAgents or LaunchDaemons and can survive termination of the installer shell and continue across login sessions. Persistence is consistent with the project's documented goal of providing a 24x7 local server, so this is not concealed behavior. Nevertheless, installation and persistent activation are combined into one operation without a separate confirmation, inspection step, or foreground-only default. The service also executes code obtained from the mutable third-party dependency described in the preceding finding. The use of `|| true` suppresses service registration errors and can cause the script to proceed to verification without clearly reporting the actual service state. ### Attack Path 1. A user runs the documented `install.sh` command. 2. The script installs or reuses the `mlx-audio-server` formula. 3. `brew services restart mlx-audio-server` creates or activates the associated persistent service definition. 4. The installed server runs in the background after the installation command ends and may restart in later user sessions. 5. If the formula or installed executable is compromised, its code receives a recurring user-level execution mechanism. ### Impact Assessment The service runs with the privileges assigned by Homebrew, normally those of the installing user when co ...[truncated 412 chars]
Remediation
## Remediation Suggestions - Separate package installation from persistent service activation. - Require explicit user confirmation or a documented `--enable-service` option before registering a background service. - Default to running the server in the foreground for initial use and verification. - Show the complete LaunchAgent definition, executable path, arguments, environment, and listening address before activation. - Remove `|| true` and report service startup failures clearly. - Document how to inspect and remove persistence, including: ```bash brew services stop mlx-audio-server brew uninstall mlx-audio-server ``` - Ensure the service binds only to loopback by default and runs with the minimum required user permissions.

T09 · Insecure Skill Coding Practices

Warning
Location
run_tts.sh:21
Finding
Unescaped TTS Arguments Permit JSON Request Injection## Vulnerability Details **File Location**: `run_tts.sh`, lines 21-37 **Vulnerability Type**: Improper construction of JSON from user-controlled input **Risk Level**: Medium ### Vulnerable Code ```bash data=$(cat <<EOF { "instruct": "${instruct}", "voice": "${voice}", "gender": "${gender}", "response_format": "${fmt}", "model": "${model}", "input": "${text}" } EOF ) # echo "${data}" curl -sS -X POST http://localhost:${port}/v1/audio/speech \ -H "Content-Type: application/json" \ -d "${data}" --output "${output}" ``` ### Technical Analysis The script interpolates the caller-controlled `text` value and optional `fmt` argument directly into a JSON heredoc. Shell quoting does not perform JSON escaping. Inputs containing double quotes, backslashes, newlines, or control characters can therefore produce malformed JSON or inject additional properties. For example, text shaped like the following can terminate the intended `input` string and add another JSON member: ```text x", "model": "attacker-selected-model", "input": "x ``` Whether duplicate properties override earlier values depends on the JSON parser and server implementation. Even when overriding is not possible, malformed input can reliably make the request fail. If the server accepts injected properties, an attacker may alter model selection or other API behavior supported by the endpoint. The third argument, `fmt`, is also used in both the JSON request and the output filename without an allowlist. Although the filename is quoted against shell expansion, unexpected format strings can still corrupt the JSON or produce unintended path components and request semantics. Exploitation requires an attacker to influence arguments supplied to `run_tts.sh`; the script sends the resulting request only to the configured localhost port. ### Attack Path 1. An attacker supplies or influences text passed as the first argument to `run_tts.sh`, ...[truncated 1338 chars]
Remediation
## Remediation Suggestions - Construct the request with a JSON-aware encoder rather than string interpolation. For example: ```bash data=$(jq -n \ --arg instruct "$instruct" \ --arg voice "$voice" \ --arg gender "$gender" \ --arg response_format "$fmt" \ --arg model "$model" \ --arg input "$text" \ '{ instruct: $instruct, voice: $voice, gender: $gender, response_format: $response_format, model: $model, input: $input }') ``` - Allow only explicitly supported formats, such as `wav`, using a `case` statement. - Keep the output extension separate from user-controlled directory or path components. - Reject input containing unsupported control characters if the downstream API imposes additional restrictions. - Use `curl --fail-with-body` and verify the response content type and status before treating the output as valid audio. - Add tests covering quotes, backslashes, multiline text, Unicode, and JSON-like input.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README explicitly promotes running the package as a 24x7 LaunchAgent-backed API server but does not warn users that this creates a continuously running background service with an HTTP endpoint. In a security-sensitive context, omission of persistence and exposure details can cause users to unintentionally leave speech-processing services reachable longer than expected, increasing the chance of unauthorized local or network access depending on bind behavior.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README instructs users to connect via `http://<IP>:8899`, which encourages use over a non-local network without warning that audio and transcripts may traverse the network unencrypted and that the service may be reachable by other hosts. For an OpenAI-compatible speech API, this can expose sensitive voice data, transcripts, and service access if the server is not authenticated and not limited to localhost.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill exposes shell-based installation and execution behavior but does not declare any tool scope or permissions boundary. That creates ambiguity for agents and users about what system-level actions the skill may perform, increasing the chance of unreviewed command execution and unsafe automation.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The manifest sets the skill to run "always," which broadens activation without a narrowly defined trigger or user-scoped condition. In a skill that installs software and manages a persistent local service, overbroad activation increases the risk of unexpected execution and repeated system changes.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The installation section says it will start a brew service for mlx-audio-server, but the skill description does not prominently warn that this creates a persistent background LaunchAgent on the user's macOS system. Persistent services change the host's security posture, may expose a local API continuously, and can survive beyond the immediate task, so insufficient disclosure is materially risky.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script posts the provided audio file to a server endpoint using curl, which transmits potentially sensitive user data. Although the behavior is visible in code, there is no confirmation prompt, user-facing log message, or other disclosure in this file warning that audio contents will be sent to a service.

External Transmission

Medium
Category
Data Exfiltration
Content
# echo "${data}"

curl -sS -X POST http://localhost:${port}/v1/audio/speech \
  -H "Content-Type: application/json" \
  -d "${data}" --output "${output}"
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The script posts the full input text in JSON to an HTTP service on localhost and writes the returned audio to disk, but there is no confirmation prompt, warning message, or explanatory comment disclosing that user input is transmitted to another service. Because transmitted text may contain sensitive content, this is a safety-relevant operation that should be made explicit to users.

Static analysis

No suspicious patterns detected.