Back to skill

Security audit

Affinity Readonly

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent read-only Affinity CRM helper, but it can send the Affinity API key to any URL placed in AFFINITY_API_BASE.

Review before installing. Use only with a read-only, least-privileged Affinity token, avoid setting AFFINITY_API_BASE except in controlled testing, and prefer a version that fixes the API host to https://api.affinity.co or validates an explicit trusted allowlist. Rotate the token if this has already run where AFFINITY_API_BASE may have been manipulated.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/affinity_get.sh:20
Finding

Affinity API Key Disclosure Through Unrestricted API Base Override

Content
View full analysis
&2 exit 2 fi # Prevent accidental non-GET by only supporting this script + curl GET invocation. url="${base}${endpoint}" if [[ -n "$query" ]]; then url+="?${query}" fi # Use Bearer token auth for Affinity API. # Do not echo command with key. resp="$(curl -fsS --get \ -H "Accept: application/json" \ -H "Authorization: Bearer ${AFFINITY_API_KEY}" \ "$url")" ``` The override is explicitly documented in `SKILL.md:34`: ```markdown - Base URL defaults to `https://api.affinity.co` and can be overridden with `AFFINITY_API_BASE` ``` ### Technical Analysis The script obtains the request destination from the environment variable `AFFINITY_API_BASE` without validating its scheme, hostname, or port. It then attaches `AFFINITY_API_KEY` as a Bearer token to a request sent to that destination. Although transmitting the token to the official Affinity API is necessary for the declared functionality, allowing an unrestricted destination is not. A malicious or compromised environment can redirect the request to an attacker-controlled server. The comments and documentation promise that the key will not be printed or logged, but they do not prevent it from being disclosed over the network. The endpoint check only verifies that the endpoint begins with `/`; it does not ensure that the completed URL belongs to `api.affinity.co`. Consequently, the credential’s trust boundary is controlled by mutable process configuration rather than a fixed or allowlisted service identity. ### Attack Path 1. An attacker gains the ability to influence the Skill’s environment, launch configura ...[truncated 1391 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill invokes shell commands and external scripts but does not declare an explicit tool scope such as allowed-tools or permissions. That creates a policy gap where an agent may be permitted broader shell usage than intended, increasing the chance of unauthorized command execution, environment inspection, or misuse of local capabilities beyond the stated read-only Affinity workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This shell script performs an authenticated HTTP request using the AFFINITY_API_KEY, which is a sensitive credential, but the only disclosure is in comments intended for readers of the code. There is no runtime notice, confirmation, or other user-facing warning that the script will transmit the bearer token to the configured API endpoint.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.