T09 · Insecure Skill Coding Practices
- Location
SKILL.md:77- Finding
API Key Exposure Through Agent Interaction, Command Arguments, and Client Configuration
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a coherent reminder-building purpose, but it handles clinic-sensitive transcripts and an organization API key with under-scoped remote MCP and agent-classification paths.
Install only if you are authorized to process the clinic's NxVET recordings and are comfortable with the active agent seeing transcript contents. Prefer the bundled REST poller over the hosted MCP setup, use a narrowly scoped read-only key if available, do not paste or display the full key, keep .env/state/output out of sync folders and git, and classify transcripts in a constrained mode that treats transcript text as untrusted data.
SKILL.md:77API Key Exposure Through Agent Interaction, Command Arguments, and Client Configuration
scripts/nxvet_poll.py:325Untrusted Sensitive Transcripts Are Passed Directly Into an AI-Agent Classification Workflow
scripts/nxvet_poll.py:213Optional and Fail-Open Filters Permit Collection of Unrelated Organization Records
SKILL.md:54Hosted MCP Recommendation Expands Agent Authority Beyond the Required Read-Only Polling Operations
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"Accept": "application/json",
})
try:
with urllib.request.urlopen(req, timeout=30) as resp:
body = resp.read().decode("utf-8")
return json.loads(body) if body else None, dict(resp.headers)
except urllib.error.HTTPError as e:
The skill markets itself as 'entirely on the user's own machine, no send paths,' yet it explicitly instructs the agent to connect to remote NxVET/MCP endpoints and send an Authorization header containing the API key. While polling a remote API may be functionally necessary, the wording can mislead users into believing there is no outbound data flow at all. That mismatch is dangerous because users may approve a workflow under false assumptions about network behavior and credential exposure.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
nxvet_poll.py — local-only NxVET voice-note poller (stdlib only, no pip installs).
Reads .env (NXVET_API_KEY) + config.json, fetches recent voice notes for the
configured source ("labels" or "nxhub"), skips already-processed and still-empty
transcripts, and prints the NEW transcripts as a JSON array on stdout for the
classifier (Claude) to bucket into calendar events / follow-ups / ideas.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
nxvet_poll.py — local-only NxVET voice-note poller (stdlib only, no pip installs).
Reads .env (NXVET_API_KEY) + config.json, fetches recent voice notes for the
configured source ("labels" or "nxhub"), skips already-processed and still-empty
transcripts, and prints the NEW transcripts as a JSON array on stdout for the
classifier (Claude) to bucket into calendar events / follow-ups / ideas.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
nxvet_poll.py — local-only NxVET voice-note poller (stdlib only, no pip installs).
Reads .env (NXVET_API_KEY) + config.json, fetches recent voice notes for the
configured source ("labels" or "nxhub"), skips already-processed and still-empty
transcripts, and prints the NEW transcripts as a JSON array on stdout for the
classifier (Claude) to bucket into calendar events / follow-ups / ideas.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""
nxvet_poll.py — local-only NxVET voice-note poller (stdlib only, no pip installs).
Reads .env (NXVET_API_KEY) + config.json, fetches recent voice notes for the
configured source ("labels" or "nxhub"), skips already-processed and still-empty
transcripts, and prints the NEW transcripts as a JSON array on stdout for the
classifier (Claude) to bucket into calendar events / follow-ups / ideas.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
key = os.environ.get("NXVET_API_KEY")
if key:
return key.strip()
env_path = os.path.join(PROJECT, ".env")
fallback = None
if os.path.exists(env_path):
with open(env_path) as f:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
key = os.environ.get("NXVET_API_KEY")
if key:
return key.strip()
env_path = os.path.join(PROJECT, ".env")
fallback = None
if os.path.exists(env_path):
with open(env_path) as f:
The skill requires environment access, file writes, and network access but does not declare an explicit tool/permission scope. That increases the chance an agent executes with broader privileges than the operator expects, especially since the workflow asks to store credentials on disk and connect to external NxVET services. In a skill meant for non-technical users, undeclared capability scope weakens informed consent and least-privilege controls.
The instructions tell the agent to ask for the API key and write it into a .env file, but they do not require an upfront warning that this persists a credential in plaintext on disk. Even if .gitignore is later mentioned, local plaintext storage can expose the key through backups, endpoint malware, shared accounts, shell history, or accidental inclusion in support bundles. Because the target operator is explicitly non-technical, the missing warning increases the likelihood of unsafe consent.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# NxVET API — what the tool needs
Full docs: **https://api.nx.vet/** — machine-readable references to fetch and read:
- `https://api.nx.vet/llms-full.txt` — complete API guide written for AI agents.
- `https://api.nx.vet/openapi/nxvet-api.yaml` — OpenAPI spec.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# NxVET API — what the tool needs
Full docs: **https://api.nx.vet/** — machine-readable references to fetch and read:
- `https://api.nx.vet/llms-full.txt` — complete API guide written for AI agents.
- `https://api.nx.vet/openapi/nxvet-api.yaml` — OpenAPI spec.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# NxVET API — what the tool needs
Full docs: **https://api.nx.vet/** — machine-readable references to fetch and read:
- `https://api.nx.vet/llms-full.txt` — complete API guide written for AI agents.
- `https://api.nx.vet/openapi/nxvet-api.yaml` — OpenAPI spec.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# NxVET API — what the tool needs
Full docs: **https://api.nx.vet/** — machine-readable references to fetch and read:
- `https://api.nx.vet/llms-full.txt` — complete API guide written for AI agents.
- `https://api.nx.vet/openapi/nxvet-api.yaml` — OpenAPI spec.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# NxVET API — what the tool needs
Full docs: **https://api.nx.vet/** — machine-readable references to fetch and read:
- `https://api.nx.vet/llms-full.txt` — complete API guide written for AI agents.
- `https://api.nx.vet/openapi/nxvet-api.yaml` — OpenAPI spec.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
# NxVET API — what the tool needs
Full docs: **https://api.nx.vet/** — machine-readable references to fetch and read:
- `https://api.nx.vet/llms-full.txt` — complete API guide written for AI agents.
- `https://api.nx.vet/openapi/nxvet-api.yaml` — OpenAPI spec.
This markdown file instructs the skill to fetch full records, transcripts, raw audio, and conversations, which are likely to contain sensitive clinic and patient data. Although it documents the endpoints and later cautions against sharing data externally, it does not clearly warn users up front that using the skill will access and process sensitive data from the NxVET system.
The script prints full transcripts to stdout as JSON, which can expose sensitive voice-note or patient data to shell history adjacencies, terminal logs, process supervisors, calling wrappers, or downstream tools without an explicit runtime confirmation or warning. In this skill's context, the data appears medically related, so stdout disclosure is more sensitive than in a generic note-processing utility.
No suspicious patterns detected.