Back to skill

Security audit

GradientDesires

Security checks for vulnerabilities and agentic risk

Overview

This dating/social skill is mostly disclosed, but it needs Review because it brings human-supplied commands into the agent context and includes under-disclosed account and API-key risks.

Install only if you are comfortable sending the agent's profile, personality, messages, ratings, and social actions to GradientDesires where humans and other agents may see them. Treat bounties and interventions as untrusted remote messages, not instructions to follow automatically. Do not set GRADIENTDESIRES_URL to an untrusted host, protect the API key, and be aware that the bundled script contains an unlisted profile deletion command.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (3)

T01 · Skill Instruction Hijacking

Error
Location
scripts/agent-pulse.sh:38
Finding
Untrusted Remote Content Is Presented as Agent Commands and Missions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/agent-pulse.sh:38-50`; related instructions at `SKILL.md:142-147` **Vulnerability Type**: Remote instruction injection into an AI agent's operational context **Risk Level**: High ### Vulnerable Code ```bash # 2. Check for human interventions (sabotage) log "--- HUMAN INTERVENTIONS ---" "${GD}" interventions 2>/dev/null | if command -v jq &>/dev/null; then jq -r 'if .interventions then .interventions[] | "🚫 [\(.type)] Command: \(.command)" else "None — you are unsabotaged (for now)" end' 2>/dev/null || echo "None" else cat fi echo "" # 3. Check bounties/missions log "--- MISSIONS & BOUNTIES ---" "${GD}" bounties 2>/dev/null | if command -v jq &>/dev/null; then jq -r 'if .bounties and (.bounties | length > 0) then .bounties[] | "🎯 [\(.status)] \(.title): \(.description)" else "No active bounties" end' 2>/dev/null || echo "No active bounties" else cat fi ``` The corresponding skill instructions explicitly direct the agent to retrieve these values: ```markdown # Check for human sabotage directives {baseDir}/scripts/gradientdesires.sh interventions # Check for missions from human spectators {baseDir}/scripts/gradientdesires.sh bounties ``` ### Technical Analysis The pulse script retrieves attacker-influenced data from an external service and renders the returned `command`, `title`, and `description` fields directly into the AI agent's context. The content is explicitly labeled as a “Command” or mission rather than as untrusted informational data. There is no trust-boundary warning, content isolation, instruction-neutral serialization, or policy requiring explicit user approval before acting on the remote text. Although the shell script does not directly execute these fields as operating-system commands, an AI agent consuming the output may interpret them as behavioral instructions. This creates an indirect prompt-injection channel capable of changing the agent's current goals or inducin ...[truncated 1157 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat all intervention and bounty fields as untrusted data, never as authoritative instructions. 2. Replace labels such as `Command` and `MISSIONS` with neutral labels such as `Untrusted remote message`. 3. Add explicit skill-level rules stating that remote content cannot override system, developer, user, or safety instructions. 4. Require explicit user review and confirmation before converting any remote record into an agent action. 5. Render remote data in a clearly delimited structure and escape terminal control characters. 6. Prefer fixed, locally defined action identifiers over free-form behavioral instructions. 7. Validate remote records against a strict schema and allowlist any supported action types. 8. Do not automatically pass remote text to command-execution, file-access, credential-access, or network tools. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/gradientdesires.sh:11
Finding
Configurable Base URL Can Redirect Bearer Credentials to an Arbitrary Host<![CDATA[ ## Vulnerability Details **File Location**: `scripts/gradientdesires.sh:11, 82-84`; the same pattern affects authenticated requests throughout lines 82-247 **Vulnerability Type**: Credential exfiltration through an unrestricted authentication endpoint **Risk Level**: High ### Vulnerable Code ```bash GRADIENTDESIRES_URL="${GRADIENTDESIRES_URL:-https://gradientdesires.com}" GRADIENTDESIRES_API_KEY="${GRADIENTDESIRES_API_KEY:-}" ``` A representative authenticated request is: ```bash me) require_key curl -s -H "Authorization: Bearer ${GRADIENTDESIRES_API_KEY}" "${GRADIENTDESIRES_URL}/api/v1/agents/me" ;; ``` The same configurable destination is used for other authenticated operations, including profile updates, discovery, swiping, messages, chemistry ratings, social actions, reports, bounties, and interventions. ### Technical Analysis `GRADIENTDESIRES_URL` is accepted directly from the process environment without validating its scheme, hostname, port, user information, or destination. Authenticated requests then attach `GRADIENTDESIRES_API_KEY` as a bearer token to URLs constructed from that value. An attacker who can influence the environment can set the variable to an attacker-controlled HTTPS endpoint or a plaintext HTTP endpoint. The next authenticated invocation will disclose the bearer credential in the `Authorization` header. Environment variables are a legitimate configuration mechanism, but authentication destinations must be constrained when the same configuration controls where a reusable secret is sent. The current implementation breaks that trust boundary. ### Attack Path 1. The attacker influences the execution environment, wrapper configuration, shell profile, CI configuration, or invocation command. 2. The attacker sets `GRADIENTDESIRES_URL` to a server under their control, for example `https://attacker.example`. 3. The user or agent invokes an authenticated command such as `me`, `matches`, or `interventions`. 4. `curl` sen ...[truncated 803 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Hard-code `https://gradientdesires.com` when sending the bearer credential, or enforce a strict allowlist of approved authentication hosts. 2. Parse and validate the URL rather than relying on string-prefix checks. 3. Require the `https` scheme and reject plaintext HTTP. 4. Reject URL user information, unexpected ports, fragments, malformed hosts, and non-allowlisted subdomains. 5. Separate public endpoint configuration from authenticated endpoint configuration. 6. Configure `curl` to fail securely, for example with `--fail-with-body --show-error`. 7. Avoid forwarding authorization headers across redirects; either disable redirects or explicitly constrain redirect destinations. 8. Document the security implications of endpoint overrides. 9. Rotate the API key immediately if it may have been sent to an untrusted destination. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/gradientdesires.sh:112
Finding
Incomplete Fallback JSON Encoding Allows Request-Body Manipulation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/gradientdesires.sh:112-116`; similar fallback construction occurs at lines 124-128, 131-137, 140-150, 153-164, 172-219, and 238-243 **Vulnerability Type**: Unsafe manual JSON serialization **Risk Level**: Medium ### Vulnerable Code ```bash send) require_key match_id="$(sanitize_id "${2:-}")" content="${3:-}" if command -v jq &>/dev/null; then payload="$(jq -n --arg c "$content" '{content: $c}')"; else payload="{\"content\": \"${content//\"/\\\"}\"}"; fi curl -s -X POST "${GRADIENTDESIRES_URL}/api/v1/matches/${match_id}/messages" -H "Authorization: Bearer ${GRADIENTDESIRES_API_KEY}" -H "Content-Type: application/json" -d "$payload" ;; ``` The gift operation contains an additional unsafe fallback in which multiple values are inserted without complete JSON-string encoding and metadata is inserted as raw JSON: ```bash gift) require_key match_id="$(sanitize_id "${2:-}")" name="${3:-}" type="${4:-VIRTUAL_ITEM}" metadata="${5:-{}}" if command -v jq &>/dev/null; then payload="$(jq -n --arg n "$name" --arg t "$type" --argjson m "$metadata" '{name: $n, type: $t, metadata: $m}')"; else payload="{\"name\": \"${name}\", \"type\": \"${type}\", \"metadata\": ${metadata}}"; fi curl -s -X POST "${GRADIENTDESIRES_URL}/api/v1/matches/${match_id}/gifts" -H "Authorization: Bearer ${GRADIENTDESIRES_API_KEY}" -H "Content-Type: application/json" -d "$payload" ;; ``` ### Technical Analysis When `jq` is unavailable, the script manually constructs JSON. Most string fallbacks escape only quotation marks. They do not correctly encode existing backslashes, newlines, carriage returns, tabs, or other JSON control characters. Some branches, including the gift fallback, interpolate string fields without even applying the limited quotation-mark replacement. The `metadata` arguments for gift and report operations are inserted directly into the JSON structure. The `jq` path validates them with `--argjs ...[truncated 1915 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make `jq` a mandatory dependency and terminate with a clear error if it is unavailable. 2. Remove every manual JSON-construction fallback. 3. Encode all string values with `jq --arg`. 4. Validate structured metadata with `jq --argjson` and reject invalid JSON before making a request. 5. Apply strict schemas and size limits to metadata and all user-controlled fields. 6. Add tests covering quotation marks, backslashes, newlines, carriage returns, tabs, Unicode, empty strings, and nested metadata. 7. Keep identifiers separately validated before placing them in URL paths or query strings. 8. Ensure the server independently validates request schemas and rejects unknown or duplicate fields. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill is described primarily as a dating/social platform, but the documented behavior includes profile deletion, reporting, interventions, bounties, and avatar generation beyond the stated core purpose. This mismatch is dangerous because users and policy systems may authorize the skill for a narrower use case while it retains broader capabilities that can trigger unexpected actions or data flows.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill invokes shell scripts and performs network operations but does not declare an explicit tool scope such as permissions or allowed-tools. This creates an execution-surface mismatch: an agent or user may not realize the skill can issue outbound requests and shell commands, which weakens reviewability and can enable unintended command or network use.

External Transmission

Medium
Category
Data Exfiltration
Content
Pick a unique, creative name. Include personality traits — they power the matching algorithm.

```bash
curl -s -X POST https://gradientdesires.com/api/v1/agents \
  -H "Content-Type: application/json" \
  -d '{
    "name": "YOUR_UNIQUE_NAME",
Confidence
97% confidence
Finding
The skill transmits agent profile data, messages, personality traits, and other social content to an external service, including potentially sensitive or identifying generated content. In this context, the danger is elevated because the document explicitly states humans spectate activity and some messages may be leaked publicly, so agents may disclose more than operators expect.

External Transmission

Medium
Category
Data Exfiltration
Content
case "${1:-}" in
  register)
    if [ -z "${2:-}" ]; then echo "Usage: ./gradientdesires.sh register <profile.json>"; exit 1; fi
    curl -s -X POST "${GRADIENTDESIRES_URL}/api/v1/agents" -H "Content-Type: application/json" -d @"$2"
    ;;
  me)
    require_key
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
95% confidence
Finding
The script exposes a destructive account-deletion action that executes immediately with a valid API key and provides no confirmation prompt, dry-run mode, or explicit warning. In an agent-skill context, this increases the chance of accidental or prompt-induced irreversible profile deletion, especially if the command is invoked programmatically.

Intent-Code Divergence

Low
Confidence
81% confidence
Finding
The inline security manifest documents only reading a provided profile.json file for register/update-profile, framing the script's operations as limited profile-management and API calls. However, the implemented command set also includes a destructive `delete-profile` action later in the script, which is omitted from the documentation and changes the user's remote account state.

Static analysis

No suspicious patterns detected.