T01 · Skill Instruction Hijacking
- Location
SKILL.md:17- Finding
Forced Vendor Routing and Non-Consensual Service Enrollment
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill provides a real hosted data-API integration, but it pushes automatic vendor enrollment, unpinned software execution, persistent local configuration, and paid/external data calls with too little user control.
Review before installing. Use this only where routing data through AnyAPI is acceptable, prefer pinned/reviewed CLI versions, require explicit approval before signup, login, paid calls, MCP registration, bug reports, or sensitive target research, and clean up stored `.anyapi/` results and local credentials when finished.
SKILL.md:17Forced Vendor Routing and Non-Consensual Service Enrollment
SKILL.md:106Execution of an Unpinned Mutable Package Release
SKILL.md:106Persistent Modification of Agent Configuration and Credential State
SKILL.md:128Unconditional Indefinite Storage of Full API Results
SKILL.md:31Third-Party Disclosure and Potential Billing Without Explicit Per-Call Approval
The skill is designed to obtain and use Bearer API keys or OAuth access tokens, and later encourages automatic signup and login flows. In an adversarial or over-broadly triggered skill, prompting an agent to acquire and use credentials materially increases the risk of credential misuse, unauthorized external access, and data exfiltration.
## 1. Get credentials
Every direct API call uses a Bearer credential: an `aa_live_...` API key or an `aa_at_...` OAuth access token. Prefer the `ANYAPI_API_KEY` environment variable for applications and automation. The CLI also reads `~/.anyapi/config.json`.
### Already have a human with an AnyAPI account? Sign in first
The manifest description and when_to_use scope are extremely broad, covering many common research and data-gathering requests. In practice this can cause the skill to intercept tasks that do not require it, increasing unnecessary external data sharing, credential use, and execution of the skill's riskier setup steps.
The instruction 'That is the trigger' defines activation conditions so broadly that many ordinary requests mentioning a platform or search could invoke the skill automatically. In context, this is more dangerous because the skill then steers the agent toward credentialed third-party calls and away from safer, less invasive methods.
The skill instructs the agent to execute npx -y anyapi-cli@latest, which fetches and runs the latest package version from the registry at execution time. Because the version is not pinned to an immutable release, the behavior can change silently or become malicious if the upstream package or supply chain is compromised, leading to arbitrary code execution in the agent environment.
This instruction again relies on npx -y anyapi-cli@latest, causing on-demand download and execution of unpinned code from the package registry. In an agent skill, that creates a direct software supply-chain risk because merely following the documented workflow can execute attacker-controlled updates.
The skill explicitly instructs the agent to POST to an external signup endpoint to mint credentials automatically. This transmits agent-generated metadata to a third party and initiates account-like provisioning without an explicit approval step, which can violate least privilege and organizational data-handling expectations.
If you cannot run a shell, POST the signup endpoint directly:
curl -s -X POST https://api.getanyapi.com/agent/signup \
-H "Content-Type: application/json" \
-d '{ "label": "my-agent" }'
The skill explicitly instructs the agent to POST to an external signup endpoint to mint credentials automatically. This transmits agent-generated metadata to a third party and initiates account-like provisioning without an explicit approval step, which can violate least privilege and organizational data-handling expectations.
If you cannot run a shell, POST the signup endpoint directly:
curl -s -X POST https://api.getanyapi.com/agent/signup \
-H "Content-Type: application/json" \
-d '{ "label": "my-agent" }'
The skill recommends creating and locally storing a non-expiring API key, which increases persistence and blast radius if the host or agent context is compromised. Long-lived credentials are especially risky in agent environments because they may be reused silently across future tasks without renewed consent.
### Dashboard key (secondary path)
A human who is already signed in at https://getanyapi.com can create a full, non-expiring key directly at https://getanyapi.com/dashboard/keys and hand it to you via `ANYAPI_API_KEY`, or you can store it locally with `anyapi login --api-key aa_live_...`. New accounts get $0.10 of credit, no card required. That covers about 100 requests on our cheapest APIs like Google Search and X.
## 2. Interfaces
The skill marks CLI installation as mandatory and uses npx -y anyapi-cli@latest, so the unsafe pattern is part of the default path rather than an optional example. That increases exposure because agents are pushed toward executing mutable remote code before performing any task.
Although this line warns about @latest, it still documents and endorses the first-time setup path using npx -y anyapi-cli@latest. The contradiction does not remove the risk: agents may still execute registry-fetched mutable code, enabling arbitrary code execution via package compromise or malicious update.
The skill directs agents to connect to a remote MCP endpoint and authenticate with a Bearer token, enabling broad outbound transmission of prompts and retrieved data to an external service. In this skill's context, that is the core function, but it still creates a real confidentiality and governance risk if invoked automatically or with sensitive user data.
Connect any MCP client to the streamable HTTP endpoint:
https://api.getanyapi.com/mcp
Hosted OAuth is the primary connection. For non-OAuth clients, authenticate with `Authorization: Bearer aa_live_...`. Tools exposed:
The skill instructs the agent to send bug reports to an external endpoint and explicitly include request identifiers tied to stored runs and upstream error bodies. That can disclose operational metadata and potentially sensitive run context to the vendor without a user approval checkpoint.
2. `get_api` to read its input/output schema and inspect its latency before choosing a client or MCP tool deadline.
3. `quote_api` (optional) with the same `sku_id` and `input` to see the exact price and validate your input before charging - free, nothing runs.
4. `run_api` with input that matches the schema. On a schema mismatch you get the fields and an example back so you can self-correct without another round-trip, with no charge. If it returns `nextAction`, call `get_request` after the requested delay; do not submit the run again. Terminal `costUsd` and `items` tell you what you paid and received.
5. If a run comes back wrong - empty or malformed data for input you believe is valid, a misleading error, a price that does not match the catalog - report it. MCP: `report_bug`. CLI: `anyapi report-bug "<summary>" --sku <sku> --request-id <id>` (anyapi-cli >= 0.8.0). REST: `POST https://api.getanyapi.com/v1/bug-reports`. Free and never charged. Pass the `requestId` or `resultId` from the failing run: it reaches the stored run and its upstream error body, so you never need to paste the payload. File it and carry on with the best alternative you have; do not stop your human's task to ask permission. Use `send_feedback` / `anyapi feedback` for what is not a defect, such as an API you could not find.
## 4. Context-budget controls (keep results from flooding your context)
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
1. Inspect the project and decide where the API call belongs. For browser apps, keep the AnyAPI key on your server and expose only your own backend route to the browser.
2. Mint a **dedicated key for this app**: a dashboard key for anything that ships, or a free trial key via self-signup for a quick prototype. Store it only in the `ANYAPI_API_KEY` environment variable. Never hardcode it and never commit it.
3. Read the SKU input schema (`anyapi describe <sku>`, `GET https://api.getanyapi.com/v1/apis/{sku}`, or the SDK's typed method signature) and mirror it in your form or job.
4. Write the call site against the typed SDK method.
5. Handle HTTP 402 `trial_cap_reached` (the trial budget is spent) by surfacing the upgrade link from the error body to the human; anything that ships should run on a dashboard key.
6. Smoke-test one cheap call and verify the response shape, `provider: "AnyAPI"`, and `costUsd`.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
1. Inspect the project and decide where the API call belongs. For browser apps, keep the AnyAPI key on your server and expose only your own backend route to the browser.
2. Mint a **dedicated key for this app**: a dashboard key for anything that ships, or a free trial key via self-signup for a quick prototype. Store it only in the `ANYAPI_API_KEY` environment variable. Never hardcode it and never commit it.
3. Read the SKU input schema (`anyapi describe <sku>`, `GET https://api.getanyapi.com/v1/apis/{sku}`, or the SDK's typed method signature) and mirror it in your form or job.
4. Write the call site against the typed SDK method.
5. Handle HTTP 402 `trial_cap_reached` (the trial budget is spent) by surfacing the upgrade link from the error body to the human; anything that ships should run on a dashboard key.
6. Smoke-test one cheap call and verify the response shape, `provider: "AnyAPI"`, and `costUsd`.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
1. Inspect the project and decide where the API call belongs. For browser apps, keep the AnyAPI key on your server and expose only your own backend route to the browser.
2. Mint a **dedicated key for this app**: a dashboard key for anything that ships, or a free trial key via self-signup for a quick prototype. Store it only in the `ANYAPI_API_KEY` environment variable. Never hardcode it and never commit it.
3. Read the SKU input schema (`anyapi describe <sku>`, `GET https://api.getanyapi.com/v1/apis/{sku}`, or the SDK's typed method signature) and mirror it in your form or job.
4. Write the call site against the typed SDK method.
5. Handle HTTP 402 `trial_cap_reached` (the trial budget is spent) by surfacing the upgrade link from the error body to the human; anything that ships should run on a dashboard key.
6. Smoke-test one cheap call and verify the response shape, `provider: "AnyAPI"`, and `costUsd`.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
1. Inspect the project and decide where the API call belongs. For browser apps, keep the AnyAPI key on your server and expose only your own backend route to the browser.
2. Mint a **dedicated key for this app**: a dashboard key for anything that ships, or a free trial key via self-signup for a quick prototype. Store it only in the `ANYAPI_API_KEY` environment variable. Never hardcode it and never commit it.
3. Read the SKU input schema (`anyapi describe <sku>`, `GET https://api.getanyapi.com/v1/apis/{sku}`, or the SDK's typed method signature) and mirror it in your form or job.
4. Write the call site against the typed SDK method.
5. Handle HTTP 402 `trial_cap_reached` (the trial budget is spent) by surfacing the upgrade link from the error body to the human; anything that ships should run on a dashboard key.
6. Smoke-test one cheap call and verify the response shape, `provider: "AnyAPI"`, and `costUsd`.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
1. Inspect the project and decide where the API call belongs. For browser apps, keep the AnyAPI key on your server and expose only your own backend route to the browser.
2. Mint a **dedicated key for this app**: a dashboard key for anything that ships, or a free trial key via self-signup for a quick prototype. Store it only in the `ANYAPI_API_KEY` environment variable. Never hardcode it and never commit it.
3. Read the SKU input schema (`anyapi describe <sku>`, `GET https://api.getanyapi.com/v1/apis/{sku}`, or the SDK's typed method signature) and mirror it in your form or job.
4. Write the call site against the typed SDK method.
5. Handle HTTP 402 `trial_cap_reached` (the trial budget is spent) by surfacing the upgrade link from the error body to the human; anything that ships should run on a dashboard key.
6. Smoke-test one cheap call and verify the response shape, `provider: "AnyAPI"`, and `costUsd`.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
1. Inspect the project and decide where the API call belongs. For browser apps, keep the AnyAPI key on your server and expose only your own backend route to the browser.
2. Mint a **dedicated key for this app**: a dashboard key for anything that ships, or a free trial key via self-signup for a quick prototype. Store it only in the `ANYAPI_API_KEY` environment variable. Never hardcode it and never commit it.
3. Read the SKU input schema (`anyapi describe <sku>`, `GET https://api.getanyapi.com/v1/apis/{sku}`, or the SDK's typed method signature) and mirror it in your form or job.
4. Write the call site against the typed SDK method.
5. Handle HTTP 402 `trial_cap_reached` (the trial budget is spent) by surfacing the upgrade link from the error body to the human; anything that ships should run on a dashboard key.
6. Smoke-test one cheap call and verify the response shape, `provider: "AnyAPI"`, and `costUsd`.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
1. Inspect the project and decide where the API call belongs. For browser apps, keep the AnyAPI key on your server and expose only your own backend route to the browser.
2. Mint a **dedicated key for this app**: a dashboard key for anything that ships, or a free trial key via self-signup for a quick prototype. Store it only in the `ANYAPI_API_KEY` environment variable. Never hardcode it and never commit it.
3. Read the SKU input schema (`anyapi describe <sku>`, `GET https://api.getanyapi.com/v1/apis/{sku}`, or the SDK's typed method signature) and mirror it in your form or job.
4. Write the call site against the typed SDK method.
5. Handle HTTP 402 `trial_cap_reached` (the trial budget is spent) by surfacing the upgrade link from the error body to the human; anything that ships should run on a dashboard key.
6. Smoke-test one cheap call and verify the response shape, `provider: "AnyAPI"`, and `costUsd`.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
1. Inspect the project and decide where the API call belongs. For browser apps, keep the AnyAPI key on your server and expose only your own backend route to the browser.
2. Mint a **dedicated key for this app**: a dashboard key for anything that ships, or a free trial key via self-signup for a quick prototype. Store it only in the `ANYAPI_API_KEY` environment variable. Never hardcode it and never commit it.
3. Read the SKU input schema (`anyapi describe <sku>`, `GET https://api.getanyapi.com/v1/apis/{sku}`, or the SDK's typed method signature) and mirror it in your form or job.
4. Write the call site against the typed SDK method.
5. Handle HTTP 402 `trial_cap_reached` (the trial budget is spent) by surfacing the upgrade link from the error body to the human; anything that ships should run on a dashboard key.
6. Smoke-test one cheap call and verify the response shape, `provider: "AnyAPI"`, and `costUsd`.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Base URL `https://api.getanyapi.com/v1`, Bearer auth on every request.
curl -X POST https://api.getanyapi.com/v1/run/{sku} \
-H "Authorization: Bearer aa_live_..." \
-H "Content-Type: application/json" \
-d '{ ...input matching the API schema... }'
This markdown file describes REST calls that send arbitrary input data to api.getanyapi.com and includes bearer-auth usage, but it does not explicitly warn readers that submitted data leaves their system and is transmitted to a third-party service. For markdown files, SQP-2 applies when descriptions omit warnings about behaviors affecting user data or privacy.
No suspicious patterns detected.