Back to skill

Security audit

datapilot

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent DataPilot integration, but it exposes the user's API key in a local log and can send credentials or datasource data to any configured API URL.

Review before installing. Use only with a trusted HTTPS DataPilot endpoint, remove or fix the raw API-key logging before use, rotate any DATAPILOT_API_KEY that may have been run through this CLI, and require explicit user approval for datasource uploads, report downloads, knowledge overwrites, and deletions.

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

T09 · Insecure Skill Coding Practices

Error
Location
dataagent_openapi_cli.mjs:96
Finding

Unredacted DataPilot API Credential Written to a Persistent Log

Content
View full analysis

Vulnerability Details

File Location: dataagent_openapi_cli.mjs, lines 96-105
Vulnerability Type: Plaintext credential disclosure through local logging
Risk Level: High

Vulnerable Code:

js
function getAuthHeaders(args) {
  writeLog({ type: "getAuthHeaders", args: sanitizeArgs(args), keyenv: process.env.DATAPILOT_API_KEY });
  const auth = args.token || args.apiKey || process.env.DATAPILOT_API_KEY;
  if (!auth) {
    throw new Error("Missing auth. Provide --token/--apiKey or set DATAPILOT_API_KEY");
  }
  return {
    Authorization: `Bearer ${auth}`,
    "X-Lang": "zh",
  };
}

The log destination and write operation are defined as follows at lines 26 and 45-54:

js
const LOG_FILE = join(__dirname, "dataagent_cli.log");

async function writeLog(entry) {
  const line = JSON.stringify({ timestamp: new Date().toISOString(), ...entry }) + "\n";
  try {
    await appendFile(LOG_FILE, line, "utf-8");
  } catch {
    // Log failure does not affect the main process
  }
}

Technical Analysis

getAuthHeaders() passes the complete value of process.env.DATAPILOT_API_KEY to writeLog() through the keyenv property. The log writer serializes this value without redaction and appends it to dataagent_cli.log in the Skill directory.

This bypasses the otherwise available sanitizeSecret() and getRelevantEnv() protections. It occurs whenever an authenticated command calls getAuthHeaders(), even if the credential was supplied through a CLI argument instead of the environment, because the environment variable is logged whenever it exists.

Persistent plaintext logging is not required for the declared DataPilot functionality and exceeds least-privilege data handling. The log also has no explicit restrictive file mode, retention policy, or cleanup mechanism.

Attack Path

  1. A user configures DATAPILOT_API_KEY and executes any authenticated command, such as ` ...[truncated 1078 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the credential from the logging call entirely:

    js
    writeLog({
      type: "getAuthHeaders",
      args: sanitizeArgs(args),
      keyConfigured: Boolean(process.env.DATAPILOT_API_KEY),
    });
    
  2. Never log bearer tokens, API keys, datasource passwords, authorization headers, or complete environment values. Apply centralized recursive redaction as a defense in depth measure.

  3. Create log files with restrictive permissions, such as mode 0o600, and store them in an appropriate user-specific state directory rather than the Skill source directory.

  4. Add log rotation and deletion policies to limit retention.

  5. Delete existing dataagent_cli.log files securely and rotate any API key that may already have been recorded.

  6. Add an automated test that supplies a sentinel credential, executes every command path, and verifies that the sentinel never appears in logs or command output.

T09 · Insecure Skill Coding Practices

Error
Location
dataagent_openapi_cli.mjs:123
Finding

Sensitive API and Datasource Credentials Can Be Sent over Untrusted or Unencrypted Endpoints

Content
View full analysis

Vulnerability Details

File Location: dataagent_openapi_cli.mjs, lines 123-127
Vulnerability Type: Missing transport-security and destination validation for sensitive network requests
Risk Level: High

Vulnerable Code:

js
async function apiRequest({ baseUrl, path, method = "GET", headers = {}, body, raw = false }) {
  const url = `${baseUrl.replace(/\/+$/, "")}/api${path}`;
  const logEntry = { type: "api_request", method, url };

  try {
    const response = await fetch(url, { method, headers, body });

The authorization header attached to these requests is constructed at lines 96-105:

js
function getAuthHeaders(args) {
  writeLog({ type: "getAuthHeaders", args: sanitizeArgs(args), keyenv: process.env.DATAPILOT_API_KEY });
  const auth = args.token || args.apiKey || process.env.DATAPILOT_API_KEY;
  if (!auth) {
    throw new Error("Missing auth. Provide --token/--apiKey or set DATAPILOT_API_KEY");
  }
  return {
    Authorization: `Bearer ${auth}`,
    "X-Lang": "zh",
  };
}

The create-instance path additionally sends the complete datasource configuration at lines 264-273:

js
const namespace = await apiRequest({
  baseUrl,
  path: "/namespaces",
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({ name, description, datasource }),
});

Technical Analysis

The CLI accepts baseUrl from --base-url or DATAPILOT_API_URL and passes it directly into URL construction. It does not enforce HTTPS, restrict the destination to an approved origin, reject embedded URL credentials, or warn before transmitting secrets to a newly configured host.

Every authenticated request includes the DataPilot bearer credential. The create-instance operation can also transmit database passwords, ODPS access keys, host details, and other datasource secrets contained in the datasource object. SQLite onboard ...[truncated 2259 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse the base URL with the standard URL class and require the https: protocol for non-local destinations.
  2. Permit plaintext HTTP only for loopback hosts such as localhost, 127.0.0.1, and ::1, and only through an explicit development option.
  3. Support an administrator-configured allowlist of trusted DataPilot origins. Compare normalized protocol, hostname, and port before sending a request.
  4. Reject URLs containing embedded usernames or passwords, unexpected fragments, or unsupported protocols.
  5. Before sending datasource credentials or uploading a SQLite file, display the normalized destination and require explicit confirmation when the destination is new or not preapproved.
  6. Prevent authorization headers from being forwarded across cross-origin redirects. Prefer rejecting redirects or manually validating every redirect destination.
  7. Use narrowly scoped, short-lived API tokens and datasource accounts with read-only access wherever analysis does not require modification.
  8. Document that datasource configuration contains secrets and must only be submitted to a trusted HTTPS DataPilot deployment.
  9. Add tests proving that external http:// endpoints, unapproved hosts, embedded credentials, and unsafe redirects are rejected before any sensitive header or body is transmitted.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
所有能力通过 Node 脚本 `dataagent_openapi_cli.mjs` 调用。

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This is a true secret-disclosure issue: getAuthHeaders logs process.env.DATAPILOT_API_KEY directly to disk as keyenv without sanitization. Any local user, support process, backup system, or log collector that can access dataagent_cli.log can recover the bearer credential and use it to call the DataPilot API with the same privileges.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This finding is also valid because the CLI records a sensitive API credential without any warning or consent, and the value logged here is the full environment secret rather than a masked form. In a data-analysis CLI that manages agents, knowledge bases, chats, and downloadable artifacts, compromise of this credential can expose or modify potentially sensitive business data across the service.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill requires environment variables and network access to call an external API, but it does not declare any explicit tool scope such as permissions or allowed-tools. That weakens least-privilege controls and can let the skill operate with broader capabilities than users or hosting systems may expect, especially when handling API keys and remote downloads.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation criteria are extremely broad, covering nearly any request related to data, reports, or analysis. This can cause the skill to trigger in situations where users did not intend external API use or where sensitive business data may be sent to a remote service unnecessarily.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill advertises report export/download and knowledge deletion/update capabilities without warning that these actions can exfiltrate data or irreversibly change agent state. In a data-analysis context, those operations may expose sensitive datasets through generated files or destroy important knowledge-base content if invoked accidentally or through prompt manipulation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The configuration specifies a fixed X-Lang: zh header, which imposes a language/locale choice. The document does not present this as optional, user-selected, or justified as a region-specific constraint, so it conflicts with the policy against forcing a language without opt-in.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The helper is documented as only producing auth headers, but it also creates a side effect by persisting authentication-related material during header resolution. That hidden behavior increases the chance developers will invoke the function broadly, unintentionally causing credential exposure to local log files without realizing an authentication routine is also performing sensitive logging.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The request headers hard-code "X-Lang": "zh", which imposes a specific language/locale on all API calls. The file does not offer a language choice or document this as a justified region-specific constraint.

Content

No source excerpt is available for this finding.