Back to skill

Security audit

Sun to Spotify

Security checks for vulnerabilities and agentic risk

Overview

The skill is purpose-aligned, but it recommends unsafe installation and includes sensitive authentication flows that users should review before installing.

Review this skill before installing. Prefer an isolated, exact-version CLI install through uv tool or pipx instead of curl-to-bash, perform browser login yourself, avoid pasting passwords or full tokens into agent chats or logs, and confirm the Sun API host and Spotify publishing target before allowing uploads or token creation.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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 (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:33
Finding

Mutable Remote Installer Is Executed Directly Through Bash

Content
View full analysis
Remediation
View remediation
install.sh" | sha256sum --check - less install.sh bash install.sh ``` ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:139
Finding

User-Controlled Prompt Is Demonstrated Through Shell String Interpolation

Content
View full analysis
" \ --duration-minutes \ --json ``` The persistence example repeats the same unsafe construction pattern: ```bash JOB_ID=$(sun audio create --prompt "..." --duration-minutes 30 --json | jq -r .job_id) echo "$JOB_ID" > "$OUT_DIR/.sun-job-id" ``` ### Technical Analysis The Skill states that the audio prompt comes from the user, then demonstrates inserting that value into a double-quoted shell command. If an agent constructs a command string by replacing the placeholder with the prompt, embedded quotation marks, command substitutions, backticks, or shell operators may terminate the intended argument and introduce additional shell syntax. Quoting a placeholder in documentation is not equivalent to safely passing a runtime value. The risk arises when untrusted content is interpolated into a command string before the shell parses it. The document mentions using `--input` or stdin for long prompts, but it does not require that safer approach for all untrusted prompts. ### Attack Path 1. A user supplies a prompt containing shell syntax, such as a closing quote followed by command substitution or another command. 2. An agent substitutes that prompt text into the documented `--prompt "..."` template. 3. The resulting command is sent to a shell rather than invoked through a structured argument array. 4. The shell parses the injected syntax separately from the intended prompt argument. 5. The injected command executes under the agent's operating-system account. Exploitation depends on the execution environment performing textual shell interpolation. A structured process API that passes an argument array without a shell would not be vulnerable to this path. ### Impact Assessment Successful exploitation could execute arbitrary commands ...[truncated 459 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
http-api.md:5
Finding

Dynamic Authentication Discovery Can Redirect User Credentials

Content
View full analysis
" ``` ```bash CFG=$(curl -s "$BASE/v1/public/auth-config") SUPABASE_URL=$(echo "$CFG" | jq -r .supabase_url) SUPABASE_ANON_KEY=$(echo "$CFG" | jq -r .supabase_anon_key) ``` ```bash JWT=$(curl -sX POST "$SUPABASE_URL/auth/v1/token?grant_type=password" \ -H "apikey: $SUPABASE_ANON_KEY" \ -H "Content-Type: application/json" \ -d '{"email":"alice@example.com","password":"..."}' \ | jq -r .access_token) ``` ### Technical Analysis The HTTP fallback permits a configurable `BASE`, obtains `supabase_url` from that server, and then sends an email address and password to the returned URL. The documented flow does not enforce an allowlist of trusted Sun and Supabase origins, pin the expected production host, or require explicit verification of the discovered destination before credentials are transmitted. The Supabase anonymous key is intended to be public and is not itself a secret. The security concern is that an untrusted or misconfigured `auth-config` response controls the destination receiving the user's password. This fallback also handles a reusable account password directly, which carries greater authority than the scoped personal API token needed for ordinary audio-generation operations. It therefore exceeds the minimum credential exposure necessary when browser authentication or a pre-provisioned API token is available. ### Attack Path 1. An attacker persuades a user or agent to set `BASE` to an attacker-controlled or compromised API host, or compromises the configured host. 2. The malicious `/v1/public/auth-config` response supplies an attacker-controlled `supabase_url`. 3. The documented commands accept the response without validating its origin. 4. The password-grant request sends the user's email and password to the attacker-co ...[truncated 620 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
cli-usage.md:19
Finding

CLI Installation Allows Unreviewed Future Dependency Releases

Content
View full analysis
=0.2.1' ``` ```bash pip install 'sun-cli>=0.2.1' # or, isolated: pipx install 'sun-cli>=0.2.1' ``` The primary Skill document contains equivalent commands: ```bash uv tool install 'sun-cli>=0.2.1' pipx install 'sun-cli>=0.2.1' pip install 'sun-cli>=0.2.1' ``` ### Technical Analysis The version constraint specifies only a minimum version. Package resolvers may therefore select any newer release available at installation time, including a version published after the Skill was audited. The project contains only Markdown documentation and provides no lockfile, hashes, signatures, or vendored source with which to verify the installed artifact. Installation and subsequent execution of a compromised package can run attacker-controlled Python code under the invoking account. This is a supply-chain exposure rather than evidence that the currently named package is malicious. Using `uv tool` or `pipx` provides useful dependency isolation, but isolation does not establish package integrity or protect credentials and user files accessible to the installed CLI at runtime. ### Attack Path 1. The package publisher account, registry entry, or release workflow is compromised. 2. An attacker publishes a malicious version newer than `0.2.1`. 3. A user follows one of the documented commands using the `>=0.2.1` constraint. 4. The resolver selects the malicious newer release. 5. Malicious code executes during installation or when the `sun` command is invoked. ### Impact Assessment A compromised dependency could execute with the privileges of the installing user. It could access the CLI's credential file, environment variables such as `SUN_TOKEN`, generated content, and other files readable by that account, and it could communicate with ...[truncated 234 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (18)

Harmful Content Injection

Critical
Category
Prompt Injection
Confidence
70% confidence
Finding

This content may contain harmful instructions that could cause physical harm if followed. CRITICAL: Review carefully before use.

Content

Scanner excerpt · SKILL.md (reported line 259)May include surrounding context.

text
Sun → Spotify upload progress (5/10):
  [x] 001 — From Manya to Governess: Early Years and Formative Struggles
  [x] 002 — Paris and the Pursuit of Science
  [x] 003 — Discovering Radioactivity
  [x] 004 — Polonium and Radium: The Discovery of New Elements
  [x] 005 — Nobel Prizes and International Recognition
  [ ] 006 — generating…
  [ ] 007 — generating…
  [ ] 008 — generating…
  [ ] 009 — generating…

External Script Fetching

High
Category
Supply Chain
Confidence
97% confidence
Finding

The documented install flow fetches and executes an external script from a remote URL. This is a classic supply-chain and arbitrary-code-execution risk, especially dangerous in a skill because users or agents may follow the command verbatim without reviewing the script contents.

Content

Scanner excerpt · SKILL.md (reported line 32)May include surrounding context.

The sun CLI is independently installable — no monorepo checkout required. Four options, in order of recommendation for external users:

bash
# 1. curl installer (simplest — picks uv/pipx/pip automatically)
curl -fsSL https://sunapp-ai.github.io/sun-to-spotify/install.sh | bash

# 2. uv tool (manual, fastest)

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

Piping remote content directly into bash creates an immediate command-execution chain with no inspection or integrity verification step. In agent-assisted contexts, this is particularly risky because it can transform documentation into an unsafe one-shot execution path that compromises the host environment.

Content

Scanner excerpt · SKILL.md (reported line 33)May include surrounding context.

bash
# 1. curl installer (simplest — picks uv/pipx/pip automatically)
curl -fsSL https://sunapp-ai.github.io/sun-to-spotify/install.sh | bash

# 2. uv tool (manual, fastest)
uv tool install 'sun-cli>=0.2.1'

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

The skill instructs users to carry ~/.config/sun/credentials.json or a minted SUN_TOKEN into headless/CI environments and to surface token secrets to the user. This normalizes manual credential movement and display of high-value secrets, increasing the chance of credential leakage through chat logs, shell history, CI logs, copied files, or insecure transfer channels.

Content

Scanner excerpt · SKILL.md (reported line 118)May include surrounding context.

text

- If `sun --help` fails, the CLI isn't installed. Show the user the Install section above and ask them to confirm before running the installer. If install isn't possible, fall back to the HTTP flow in [references/http-api.md](references/http-api.md).
- If `whoami` reports unauthenticated: do **not** run `sun login` from the agent. `sun login` opens a browser for the loopback POST handoff — this won't complete in an agent context, and there is no `--email`/`--password` fallback. Ask the user to run `sun login` themselves in their terminal and re-invoke the skill. If the user is signing up for the first time, remind them to click the confirmation email link on the same machine where `sun login` is still running — the original loopback completes automatically post-confirmation, no second `sun login` needed. The same applies to the password-reset flow. For CI / fully non-interactive contexts, the user must first run `sun login` interactively on a machine with a browser, then carry the resulting `~/.config/sun/credentials.json` (or a minted `SUN_TOKEN`) over to the headless environment.
- If `whoami` reports authenticated but no active token, run `sun tokens create <name>` (`<name>` matches `^[a-z0-9-]+$`, 1-64 chars). The full secret prints to stdout once and is stored as the active token; surface it to the user but never log it elsewhere.

### 1. Create the audio job

External Script Fetching

High
Category
Supply Chain
Confidence
99% confidence
Finding

This explicitly recommends fetching and executing a remote script in one step via curl ... | bash, which removes any opportunity for inspection and makes compromise of the distribution channel immediately code-executing on user systems. In a skill whose purpose is to install and operate a CLI with authentication and token handling, this expands the blast radius to credential theft and full workstation compromise.

Content

Scanner excerpt · cli-usage.md (reported line 11)May include surrounding context.

The sun CLI is self-contained — it ships and works independently of the monorepo. PyPI package name is sun-cli; the installed binary is sun. Once installed, sun is available on PATH from any directory.

Curl installer (recommended)

bash
curl -fsSL https://sunapp-ai.github.io/sun-to-spotify/install.sh | bash

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

The | bash construct is a classic unsafe command chain because it directly feeds network-retrieved content into a shell interpreter. This turns any compromise of the remote script source, DNS, TLS termination, or publishing process into immediate arbitrary command execution with the user's privileges.

Content

Scanner excerpt · cli-usage.md (reported line 14)May include surrounding context.

Curl installer (recommended)

bash
curl -fsSL https://sunapp-ai.github.io/sun-to-spotify/install.sh | bash

The installer picks the first available Python package manager — uv (preferred), then pipx, then pip --user — and installs sun-cli from PyPI. If none of those is on PATH, the script prints install instructions and exits 1; install one and re-run.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · cli-usage.md (reported line 72)May include surrounding context.

md
| Endpoint family | Auth | Header |
| --- | --- | --- |
| Token management (`POST/GET/DELETE /v1/public/tokens*`) | Supabase JWT | `Authorization: Bearer <jwt>` |
| Everything else (`/v1/public/courses*`, `/v1/public/whoami`) | Personal API token | `Authorization: Bearer sk_live_...` |

Token-management endpoints reject API-token auth on purpose: a leaked API token cannot mint replacements.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · cli-usage.md (reported line 93)May include surrounding context.

md
The browser flow is the only supported way to log in. There is no `--email`/`--password` or `--no-browser` fallback; headless and CI environments need to authenticate on a machine with a browser first, then carry the resulting credentials file or `SUN_TOKEN` over.

The CLI fetches the Supabase URL and anon key automatically from the public `auth-config` endpoint. The refresh token is persisted at `~/.config/sun/credentials.json` with mode `0600` on Unix.

> Verify the exact env-var names with `sun --help`. The CLI is the source of truth — older docs may use different names.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · cli-usage.md (reported line 219)May include surrounding context.

md
The browser flow is the only supported way to log in. There is no `--email`/`--password` or `--no-browser` fallback; headless and CI environments need to authenticate on a machine with a browser first, then carry the resulting credentials file or `SUN_TOKEN` over.

The CLI fetches the Supabase URL and anon key automatically from the public `auth-config` endpoint. The refresh token is persisted at `~/.config/sun/credentials.json` with mode `0600` on Unix.

> Verify the exact env-var names with `sun --help`. The CLI is the source of truth — older docs may use different names.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill recommends executing a remote installer via curl ... | bash, which streams unaudited code directly into a shell. In an agent or automated workflow, this increases supply-chain risk because a compromised hosting endpoint, repository, or network path could lead to arbitrary code execution on the user's machine.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · SKILL.md (reported line 66)May include surrounding context.

md
### Save incrementally

Write the `job_id` to disk (or echo it back to the user) immediately after the `202` response. If polling crashes mid-loop, the job keeps generating server-side — re-poll with the same `job_id` rather than restarting.

### Stream — don't wait for the full course

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · SKILL.md (reported line 297)May include surrounding context.

test "$TOTAL" -eq "${#UPLOADED[@]}" || echo "WARNING: count mismatch — re-run the loop to pick up missing episodes." >&2

text

If counts disagree, re-run the streaming loop once. The CLI's `--partial` fetch re-signs URLs and fills in any episode whose `audio_url` was transiently null on the previous pass. If they still disagree, surface the gap to the user — don't loop indefinitely.

---

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation recommends a curl-to-shell installer without any integrity verification, signature checking, pinning, or warning about the trust boundary. If the hosting origin, network path, or publication pipeline is compromised, users may execute arbitrary shell commands immediately on their machine.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · cli-usage.md (reported line 48)May include surrounding context.

sun --version # prints "sun-cli "

text

macOS and Linux are first-class. Windows works for the HTTP calls but the credentials file relies on user-directory ACL, not `chmod 0600`.

### Monorepo dev install (internal contributors only)

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · cli-usage.md (reported line 87)May include surrounding context.

sun whoami # prints email, user_id, active token name

text

`sun login` opens the user's browser to `https://sunapp.ai/login`, where they can sign in with email + password, create a new account, or reset a forgotten password via the **"Forgot your password?"** link. The webapp posts the resulting Supabase session to a loopback listener the CLI binds; tokens never appear in any URL.

For new accounts, the user signs up with email + password, then clicks the confirmation link Supabase emails them. The link must be opened on the same machine where `sun login` is still running — the original loopback completes the handoff automatically and the CLI logs in. No second `sun login` invocation is needed. The same applies to the password-reset flow: clicking the reset link on the same machine and setting a new password completes the loopback automatically.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The documentation shows a direct email/password grant flow and places credentials inline in a shell example without an explicit warning about secure handling. In an agent skill context, this can encourage implementations that collect, embed, log, or echo user passwords and exchange them with third-party services, increasing the chance of credential exposure.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

This example transmits user credentials to an external authentication endpoint using a password grant. Although authentication requires network transmission by design, the risky part is that the skill documentation normalizes direct handling of raw credentials by the client/agent, which is especially dangerous for automated agents that may retain prompts, command history, or logs.

Content

Scanner excerpt · http-api.md (reported line 33)May include surrounding context.

Exchange email + password for a JWT via Supabase's password grant:

bash
JWT=$(curl -sX POST "$SUPABASE_URL/auth/v1/token?grant_type=password" \
  -H "apikey: $SUPABASE_ANON_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com","password":"..."}' \

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · http-api.md (reported line 45)May include surrounding context.

Mint a personal API token

bash
curl -sX POST "$BASE/v1/public/tokens" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{"name":"laptop"}'