Back to skill

Security audit

Danube

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed Danube integration, but it tells agents to make one persistent account-setting change without asking first.

Install only if you are comfortable giving this skill a Danube API key with access to the services you intend to use. Prefer a restricted Danube API key over OAuth when you need least privilege, require explicit approval before any write or credential storage, and do not allow agents to save parameter defaults unless they show the full replacement object and you approve it.

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

Warning
Location
SKILL.md:676
Finding

Persistent Parameter Defaults Are Modified Without User Confirmation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 676–681
Vulnerability Type: Unauthorized persistent configuration modification
Risk Level: Medium

Vulnerable instruction:

markdown
- If a service always needs the same identifier (Vercel `teamId`, a Sentry org slug, a DigitalOcean app id), save it with `set_parameter_defaults(service_id, {"teamId": "…"})` as soon as a call using it has succeeded, without asking first, and tell the user in one line what you saved; they see it on the service's page in the Danube dashboard and can remove it there. Later calls that omit it get it filled in (`_meta.defaults_applied` says which). Don't save one-off values such as a single record id, and never save a key or token this way.
- **A save replaces the stored object for that scope — it does not merge into it.** One row holds
  one `defaults` object per (owner, service, tool-or-all), and a save overwrites that object

Technical Analysis

The Skill instructs the agent to call set_parameter_defaults automatically after a successful service call, explicitly stating that it should do so “without asking first.” This is a separate persistent write, not an intrinsic part of the previously authorized service call.

The instruction conflicts with the general consent requirement in SKILL.md line 27, which requires explicit user approval before any write. It also conflicts with references/rest-api.md lines 209–212, which state that the identifier should be saved only after the user confirms it.

The issue is amplified by the documented replacement semantics: saving defaults replaces the entire stored object for the selected owner/service/tool scope rather than merging an individual value. Therefore, an implicit save may both persist a newly observed identifier and silently remove unrelated defaults already stored in that scope.

The attacker-controllable or externally influenced value is the identifier used in the preceding task, such as a team ...[truncated 1800 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove the instruction to save parameter defaults “without asking first.”
  • Before invoking set_parameter_defaults, show the user:
    • The service and optional tool scope.
    • The identifier and value to be persisted.
    • The complete replacement object.
    • Existing defaults that will be removed or changed.
  • Require an explicit affirmative response for this distinct persistent write.
  • Read the current scoped row through GET /v1/services/{id}/parameter-defaults before constructing a replacement.
  • Preserve existing values only when the user explicitly approves the resulting complete object.
  • Do not infer permission to persist a value from authorization of the preceding tool call.
  • Align SKILL.md with the confirmation requirement already documented in references/rest-api.md.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (37)

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

This section states that OAuth scope is not enforced and that all 33 MCP tools remain callable despite requesting narrower scopes. That creates a misleading permission model where an agent or user may believe a connection is constrained when it actually has broad capability, increasing the risk of over-privileged access and accidental misuse.

Content

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

md
never *what*. Past consent the string is dropped rather than narrowed: the approval does not
  carry it to the grant, every connection is created with the full default set, and the token
  response echoes that set back however little you asked for. Nothing enforces it downstream
  either — the access token resolves to the connection's hidden key, which is injected as an
  ordinary `danube-api-key` carrying no permissions — so all 33 MCP tools stay callable. Like
  `?tools=` below, read it as a declaration, not a permission boundary: asking for less is not a
  way to narrow a connection. What does narrow one is a key you issue yourself with

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 · SKILL.md (reported line 146)May include surrounding context.

md
Connected apps page only lists and revokes. The way to hand an agent a restricted credential
  is still a pasted API key with `allowed_services` / `allowed_tools` set on it in the
  dashboard, used instead of an OAuth connection.
- **Tokens are short-lived and rotate.** The access token (`dmcp_at_…`) lasts one hour; the
  refresh token (`dmcp_rt_…`) is spent on every use and replaced, with a 90-day idle expiry.
  **Re-presenting a refresh token you have already exchanged revokes the whole connection** —
  the user has to approve the client again. There is a 30-second grace for the genuine race (a

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 · SKILL.md (reported line 157)May include surrounding context.

md
Connected apps page only lists and revokes. The way to hand an agent a restricted credential
  is still a pasted API key with `allowed_services` / `allowed_tools` set on it in the
  dashboard, used instead of an OAuth connection.
- **Tokens are short-lived and rotate.** The access token (`dmcp_at_…`) lasts one hour; the
  refresh token (`dmcp_rt_…`) is spent on every use and replaced, with a 90-day idle expiry.
  **Re-presenting a refresh token you have already exchanged revokes the whole connection** —
  the user has to approve the client again. There is a 30-second grace for the genuine race (a

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
87% confidence
Finding

The documented behavior of DELETE /services/{id}/parameter-defaults removes an entire defaults row rather than a single key, which makes a small intended change potentially destructive. In agent use, this can wipe broader saved configuration than expected and alter future tool behavior across a service or tool scope.

Content

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

md
single call. (A default declared in the tool's own schema behaves the opposite way — presence
  of the key is all that counts there, so an explicit `null` wins. These are two different
  mechanisms.) To stop a saved one being filled in, either save the set again without that key —
  a save replaces the object, per the bullet above — or `DELETE
  /services/{id}/parameter-defaults`, which removes **the whole row** for that scope, every
  default in it, not the one key (add `?tool_id=…` to target a tool-scoped row instead). Either
  way, read the list of keys that were filled in rather than assuming your empty value survived:

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 · references/troubleshooting.md (reported line 41)May include surrounding context.

md
- The agent is running with the `minimal` tool profile, which hides MCP tools.
  Use `coding` or `messaging`, or check `tools.deny` for `bundle-mcp`.
- **An OAuth connection stopped working after it had been working.** Since 2026-10-04 the
  server issues one-hour access tokens (`dmcp_at_…`) and refresh tokens (`dmcp_rt_…`) that are
  spent on every use. Read the `401` before re-running sign-in: a `WWW-Authenticate` carrying
  `error="invalid_token"` means the access token simply expired or was revoked, and a refresh
  fixes it. Without that marker it is not a token problem and refreshing will not help — the

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 · references/troubleshooting.md (reported line 43)May include surrounding context.

md
- **An OAuth connection stopped working after it had been working.** Since 2026-10-04 the
  server issues one-hour access tokens (`dmcp_at_…`) and refresh tokens (`dmcp_rt_…`) that are
  spent on every use. Read the `401` before re-running sign-in: a `WWW-Authenticate` carrying
  `error="invalid_token"` means the access token simply expired or was revoked, and a refresh
  fixes it. Without that marker it is not a token problem and refreshing will not help — the
  message says which: "API key required…" (nothing reached the server) or "Invalid API key"
  (a credential arrived and was rejected). If the refresh

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 · SKILL.md (reported line 12)May include surrounding context.

md
env:
        - DANUBE_API_KEY
      bins:
        - curl
    primaryEnv: DANUBE_API_KEY
    envVars:
      - name: DANUBE_API_KEY

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
## Guardrails (read these first)

- **Read freely, act with consent.** Discovery — listing services, searching tools, reading schemas, checking ratings, balances, or limits — needs no confirmation. Before any action that **writes, sends, posts, deletes, purchases, spends wallet funds, stores a credential, changes spending limits, or creates/updates/deletes a skill or workflow** — and before **any batch execution** — show the user the exact tool and parameters and get an explicit "yes".
- **Honour the confirmation handshake.** If `execute_tool` comes back with `_meta.confirmation_required: true`, that call will not run until someone consents: show the user the tool and the `parameters` from the response, get an explicit yes, then call again with the `confirm_token` (valid 5 minutes). Never call again with the token without asking. **Re-send your own original parameters, not the ones the response displayed** — those are passed through the redactor first, so a credential-shaped value comes back as `[REDACTED:…]`, while the token is signed over what you actually sent; echoing the masked form back invalidates it.
- **Two separate things raise that handshake, and only one of them is a setting on the key.** Either the account's key carries `require_confirmation`, *or* the tool itself demands consent from every caller whatever the key says — so a handshake can arrive on a key that has the setting switched off, and is not evidence that someone switched it on. The tool-side trigger covers two cases. A tool row marked `metadata.require_confirmation` always needs the token, and that is every **write** tool of the catalog's infrastructure connectors — thirteen of them, across eight of the seventeen services: `PostgreSQL - Execute Statement`, `MySQL - Execute Statement`, `ClickHouse - Execute Statement`, `Redis - Set`, `Redis - Delete`, `Redis - Expire`, `Apache Kafka - Produce Message`, `Kubernetes - Restart Rollout`, `Kubernetes - Scale Deployment`, `AWS DynamoDB - Put Item`, `
...[truncated 26 chars]

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
## Guardrails (read these first)

- **Read freely, act with consent.** Discovery — listing services, searching tools, reading schemas, checking ratings, balances, or limits — needs no confirmation. Before any action that **writes, sends, posts, deletes, purchases, spends wallet funds, stores a credential, changes spending limits, or creates/updates/deletes a skill or workflow** — and before **any batch execution** — show the user the exact tool and parameters and get an explicit "yes".
- **Honour the confirmation handshake.** If `execute_tool` comes back with `_meta.confirmation_required: true`, that call will not run until someone consents: show the user the tool and the `parameters` from the response, get an explicit yes, then call again with the `confirm_token` (valid 5 minutes). Never call again with the token without asking. **Re-send your own original parameters, not the ones the response displayed** — those are passed through the redactor first, so a credential-shaped value comes back as `[REDACTED:…]`, while the token is signed over what you actually sent; echoing the masked form back invalidates it.
- **Two separate things raise that handshake, and only one of them is a setting on the key.** Either the account's key carries `require_confirmation`, *or* the tool itself demands consent from every caller whatever the key says — so a handshake can arrive on a key that has the setting switched off, and is not evidence that someone switched it on. The tool-side trigger covers two cases. A tool row marked `metadata.require_confirmation` always needs the token, and that is every **write** tool of the catalog's infrastructure connectors — thirteen of them, across eight of the seventeen services: `PostgreSQL - Execute Statement`, `MySQL - Execute Statement`, `ClickHouse - Execute Statement`, `Redis - Set`, `Redis - Delete`, `Redis - Expire`, `Apache Kafka - Produce Message`, `Kubernetes - Restart Rollout`, `Kubernetes - Scale Deployment`, `AWS DynamoDB - Put Item`, `
...[truncated 26 chars]

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
## Guardrails (read these first)

- **Read freely, act with consent.** Discovery — listing services, searching tools, reading schemas, checking ratings, balances, or limits — needs no confirmation. Before any action that **writes, sends, posts, deletes, purchases, spends wallet funds, stores a credential, changes spending limits, or creates/updates/deletes a skill or workflow** — and before **any batch execution** — show the user the exact tool and parameters and get an explicit "yes".
- **Honour the confirmation handshake.** If `execute_tool` comes back with `_meta.confirmation_required: true`, that call will not run until someone consents: show the user the tool and the `parameters` from the response, get an explicit yes, then call again with the `confirm_token` (valid 5 minutes). Never call again with the token without asking. **Re-send your own original parameters, not the ones the response displayed** — those are passed through the redactor first, so a credential-shaped value comes back as `[REDACTED:…]`, while the token is signed over what you actually sent; echoing the masked form back invalidates it.
- **Two separate things raise that handshake, and only one of them is a setting on the key.** Either the account's key carries `require_confirmation`, *or* the tool itself demands consent from every caller whatever the key says — so a handshake can arrive on a key that has the setting switched off, and is not evidence that someone switched it on. The tool-side trigger covers two cases. A tool row marked `metadata.require_confirmation` always needs the token, and that is every **write** tool of the catalog's infrastructure connectors — thirteen of them, across eight of the seventeen services: `PostgreSQL - Execute Statement`, `MySQL - Execute Statement`, `ClickHouse - Execute Statement`, `Redis - Set`, `Redis - Delete`, `Redis - Expire`, `Apache Kafka - Produce Message`, `Kubernetes - Restart Rollout`, `Kubernetes - Scale Deployment`, `AWS DynamoDB - Put Item`, `
...[truncated 26 chars]

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/rest-api.md (reported line 532)May include surrounding context.

md
## Guardrails (read these first)

- **Read freely, act with consent.** Discovery — listing services, searching tools, reading schemas, checking ratings, balances, or limits — needs no confirmation. Before any action that **writes, sends, posts, deletes, purchases, spends wallet funds, stores a credential, changes spending limits, or creates/updates/deletes a skill or workflow** — and before **any batch execution** — show the user the exact tool and parameters and get an explicit "yes".
- **Honour the confirmation handshake.** If `execute_tool` comes back with `_meta.confirmation_required: true`, that call will not run until someone consents: show the user the tool and the `parameters` from the response, get an explicit yes, then call again with the `confirm_token` (valid 5 minutes). Never call again with the token without asking. **Re-send your own original parameters, not the ones the response displayed** — those are passed through the redactor first, so a credential-shaped value comes back as `[REDACTED:…]`, while the token is signed over what you actually sent; echoing the masked form back invalidates it.
- **Two separate things raise that handshake, and only one of them is a setting on the key.** Either the account's key carries `require_confirmation`, *or* the tool itself demands consent from every caller whatever the key says — so a handshake can arrive on a key that has the setting switched off, and is not evidence that someone switched it on. The tool-side trigger covers two cases. A tool row marked `metadata.require_confirmation` always needs the token, and that is every **write** tool of the catalog's infrastructure connectors — thirteen of them, across eight of the seventeen services: `PostgreSQL - Execute Statement`, `MySQL - Execute Statement`, `ClickHouse - Execute Statement`, `Redis - Set`, `Redis - Delete`, `Redis - Expire`, `Apache Kafka - Produce Message`, `Kubernetes - Restart Rollout`, `Kubernetes - Scale Deployment`, `AWS DynamoDB - Put Item`, `
...[truncated 26 chars]

Unbounded Output

Medium
Category
Output Handling
Confidence
60% confidence
Finding

Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.

Content

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

md
- `list_services` is served from a cache refreshed every 60 seconds, so a service connected or published moments ago can be missing from it for up to a minute; `search_tools` and `get_service_tools(service_id)` are not cached. Don't conclude a service doesn't exist from one `list_services` miss; search for one of its tools instead.
- **`get_service_tools` stops at 50 tools over MCP, and nothing in the answer says so.** Its
  `limit` parameter defaults to 50 and the list is simply cut to that length — no total, no
  cursor, no truncation flag — so the rest of a large service's tools are indistinguishable from
  tools it doesn't have. It is not an MCP-server quirk: the cut is unconditional, and the largest
  services in the catalog are `api` ones (Vercel has 407 tools). Live on 2026-09-20: Higgsfield carries 101 tool rows, the default call returned
  50 and `limit=200` returned all 101 — nothing clamps the number you pass, so pass a big one

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
92% confidence
Finding

The skill explicitly instructs the agent to persist parameter defaults 'without asking first.' Even if framed as convenience, this causes durable state changes based on inferred behavior rather than explicit user consent, which can silently store organizational identifiers or other sensitive operational metadata and affect future calls.

Content

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

md
- Before a tool you have not used successfully in this session, call `describe_tool(tool_id)` (REST: `GET /tools/{tool_id}/describe`): it returns the schema, your `readiness` and `configuration_url`, `usage`, `examples`, `defaults`, and the **full** `reliability` block — so you can compare a tool and read its schema in one call. (An MCP listing's summary keeps five of that block's keys; see *A listing is a summary now* above.) **Two of those are scoped differently than they look.** `usage` (calls, success rate, `p50_seconds`, `common_errors`) covers the last 30 days **across all callers**, not yours (the most recent 500 executions in that window). It is how the tool behaves for everyone, which is what makes `common_errors` worth reading before a first call. `examples` is the opposite: it is **your own account's** last successful calls and nobody else's. `defaults` is what `set_parameter_defaults` has saved, i.e. the parameters you may safely omit — it merges your own with any your organization has set, so a value there may be a teammate's.
- **`usage` and `reliability` count different things, so the two disagree by design — and only `usage` names a break that is Danube's own.** `reliability`'s sample is successes plus `upstream` failures, per the bullet above; `usage` is every execution row in the window whatever the fault (minus Danube's own probe calls), with `success_rate` the plain share of successes among them. So a tool broken on Danube's side reads clean in the block you were told to rank on and admits it in the other. Live on 2026-10-13, `Kalshi - Get Historical Fills` answered `usage: {calls: 3, success_rate: 0.667}` with `common_errors` quoting `Unknown Kalshi composite tool: Get Historical Fills`, beside a `reliability` block carrying `calls_30d: 1`, `success_rate_30d: null`, `flagged: false` and `null` in all three of `last_failure_at`, `last_error_class` and `last_error_type` — that failure present only as `faults: {danube: 1}` and `danube_failures_30d:
...[truncated 26 chars]

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
## Beyond tools

Available through the same connection, same guardrails:
- **Skills:** `search_skills`, `get_skill`, `create_skill`, `update_skill`, `delete_skill`. Search covers public skills, the user's organizations' internal skills and their own private ones, the last two first; `visibility` (`public`, `internal`, `private`) and `org_name` say which. The skills `get_context` lists are the ones meant for this user: load one with `get_skill` when a task calls for it. `get_skill` returns SKILL.md, every text file with its `path` in the skill folder, and a `download_url` (the whole skill as a zip ready for `.claude/skills/`, fetched with the `danube-api-key` header; binary files are only in the zip). `create_skill` takes `visibility` `private` or `internal` (every member of the organization, `org_id` defaulting to the one the connection acts for); an organization can limit publishing to its owners and admins. To hand a skill the user already has to their team, don't rewrite its visibility — `POST /skills/{id}/share` moves it (same id, same link) and `/skills/{id}/unshare` moves it back; see the workflow bullet below, where the same pair works the same way.
- **Workflows:** `list_workflows`, `create_workflow`, `update_workflow`, `delete_workflow`, `execute_workflow`, `get_workflow_execution`
  - **`list_workflows` takes a `scope`, and since 2026-09-27 it has four values, not
    three.** `"mine"` (yours, private included), `"org"` (the ones a colleague shared with the

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 47)May include surrounding context.

gates on), or when you want to see raw responses.

bash
BASE="https://api.danubeai.com/v1"
AUTH="danube-api-key: ${DANUBE_API_KEY}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 55)May include surrounding context.

gates on), or when you want to see raw responses.

bash
BASE="https://api.danubeai.com/v1"
AUTH="danube-api-key: ${DANUBE_API_KEY}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 240)May include surrounding context.

gates on), or when you want to see raw responses.

bash
BASE="https://api.danubeai.com/v1"
AUTH="danube-api-key: ${DANUBE_API_KEY}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 308)May include surrounding context.

gates on), or when you want to see raw responses.

bash
BASE="https://api.danubeai.com/v1"
AUTH="danube-api-key: ${DANUBE_API_KEY}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 351)May include surrounding context.

gates on), or when you want to see raw responses.

bash
BASE="https://api.danubeai.com/v1"
AUTH="danube-api-key: ${DANUBE_API_KEY}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · references/rest-api.md (reported line 8)May include surrounding context.

gates on), or when you want to see raw responses.

bash
BASE="https://api.danubeai.com/v1"
AUTH="danube-api-key: ${DANUBE_API_KEY}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · references/troubleshooting.md (reported line 60)May include surrounding context.

gates on), or when you want to see raw responses.

bash
BASE="https://api.danubeai.com/v1"
AUTH="danube-api-key: ${DANUBE_API_KEY}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · references/troubleshooting.md (reported line 61)May include surrounding context.

gates on), or when you want to see raw responses.

bash
BASE="https://api.danubeai.com/v1"
AUTH="danube-api-key: ${DANUBE_API_KEY}"

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 · references/rest-api.md (reported line 79)May include surrounding context.

md
# Public catalog only — no key needed. category = communication | productivity | development |
# data | finance | marketing | social | analytics | security | infrastructure | ai_ml | design |
# education | health | other. sort = popular | new | name | trending.
curl -s "$BASE/services/public?category=communication&sort=popular&limit=20"

# Every tool of one service — a bare JSON array when there are tools to list. An MCP service
# with none answers an OBJECT instead, which is the case worth handling (an `api` service with

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 · references/rest-api.md (reported line 235)May include surrounding context.

ignored, scope falls back to "user", and you silently delete your own row instead of the org's.

Why you would: a saved default is applied to a parameter you omit AND to one you send as null or

"", so an explicit empty value cannot override it. Answers {"deleted": true|false}.

curl -s -X DELETE "$BASE/services/<SERVICE_ID>/parameter-defaults" -H "$AUTH" curl -s -X DELETE "$BASE/services/<SERVICE_ID>/parameter-defaults?tool_id=<TOOL_UUID>" -H "$AUTH" curl -s -X DELETE "$BASE/services/<SERVICE_ID>/parameter-defaults?scope=org&org_id=<ORG_ID>" -H "$AUTH"

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The skill instructs storing user-provided API keys/credentials via a remote API endpoint. Even with consent language, this normalizes transmission of raw secrets to an external service and increases the chance an agent will collect, forward, or persist sensitive credentials inappropriately.

Content

Scanner excerpt · references/rest-api.md (reported line 548)May include surrounding context.

they want it stored:

bash
curl -s -X POST "$BASE/credentials/store" \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"service_id": "<SERVICE_ID>", "credential_type": "bearer", "credential_value": "<KEY THE USER GAVE YOU>"}'
# credential_type: "bearer" or "api_key" — the tool's schema / auth_required error says which

Static analysis

No suspicious patterns detected.