Back to skill

Security audit

Dingtalk Ai Table

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent DingTalk AI Table integration, but it needs Review because it can modify or delete live business data and handles a token-bearing MCP URL in ways that are under-scoped.

Install only if you are comfortable granting the skill DingTalk AI Table access that can read, create, update, and delete data. Use a least-privilege MCP URL, prefer a configured mcporter alias over passing the token URL on the command line, pin/review mcporter before installing it globally, test against non-production bases first, and require explicit confirmation before deletions, bulk imports, schema changes, or attachment uploads.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
01-list-bases.sh:4
Finding

Credential-Bearing MCP URL Exposed Through Process Arguments

Content
View full analysis

Vulnerability Details

File Location: 01-list-bases.sh:4-12
Additional Locations: 02-create-base.sh:4-14, 03-get-base.sh:4-18, 04-query-records.sh:4-20, 05-create-records.sh:4-27
Vulnerability Type: Exposure of authentication credentials through command-line arguments
Risk Level: Medium

Vulnerable Code

From 01-list-bases.sh:

bash
MCP_URL="${DINGTALK_MCP_URL}"

if [ -z "$MCP_URL" ]; then
  echo "❌ Error: DINGTALK_MCP_URL is not set"
  exit 1
fi

echo "📋 Listing all Bases..."
mcporter call "$MCP_URL" .list_bases limit=10

The same credential-bearing argument pattern appears in other wrappers:

bash
# 02-create-base.sh:4-14
MCP_URL="${DINGTALK_MCP_URL}"
BASE_NAME="${1:-My Project}"
mcporter call "$MCP_URL" .create_base baseName="$BASE_NAME"

# 03-get-base.sh:4-18
MCP_URL="${DINGTALK_MCP_URL}"
BASE_ID="${1}"
mcporter call "$MCP_URL" .get_base baseId="$BASE_ID"

# 04-query-records.sh:4-20
MCP_URL="${DINGTALK_MCP_URL}"
BASE_ID="${1}"
TABLE_ID="${2}"
mcporter call "$MCP_URL" .query_records \
  --args "{\"baseId\":\"$BASE_ID\",\"tableId\":\"$TABLE_ID\",\"limit\":10}"

# 05-create-records.sh:4-27
MCP_URL="${DINGTALK_MCP_URL}"
BASE_ID="${1}"
TABLE_ID="${2}"
mcporter call "$MCP_URL" .create_records \
  --args "{
    \"baseId\":\"$BASE_ID\",
    \"tableId\":\"$TABLE_ID\",
    \"records\":[
      {\"cells\":{\"fld_name\":\"Zhang San\",\"fld_age\":25}},
      {\"cells\":{\"fld_name\":\"Li Si\",\"fld_age\":30}}
    ]
  }"

Technical Analysis

SKILL.md explicitly states that DINGTALK_MCP_URL contains an access token and must be treated as a password. The shell wrappers expand this entire URL into an argument passed to mcporter.

Command-line arguments may be visible through process inspection facilities such as ps, /proc/<pid>/cmdline, endpoint monitoring, diagnostic collection, shell tracing, or process auditi ...[truncated 1698 chars]

Remediation
View remediation

Remediation Suggestions

  1. Register the credential-bearing URL in mcporter configuration and invoke the configured server by a non-sensitive alias:

    bash
    mcporter config add dingtalk-ai-table --url "$DINGTALK_MCP_URL"
    mcporter call dingtalk-ai-table list_bases limit=10
    

    Credential registration should be an explicit setup operation rather than repeated by every wrapper.

  2. Replace direct URL invocations in every affected wrapper:

    bash
    mcporter call dingtalk-ai-table list_bases limit=10
    
  3. Ensure that the mcporter configuration file is readable only by the owning user, for example with mode 0600, where supported.

  4. Avoid printing, tracing, or logging DINGTALK_MCP_URL. Disable shell tracing around credential-handling operations and redact URL query parameters from diagnostics.

  5. Prefer a credential-specific input mechanism, protected configuration store, or standard input if mcporter supports one.

  6. Rotate any MCP URL that may already have been captured in process-monitoring or diagnostic logs.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:169
Finding

Unpinned Global Installation of a Privileged Third-Party CLI

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:169-176
Additional Locations: GETTING_STARTED.md:5, package.json:28-30
Vulnerability Type: Unpinned supply-chain dependency installed globally
Risk Level: Medium

Vulnerable Code

From SKILL.md:

bash
npm install -g mcporter
# or
bun install -g mcporter

From GETTING_STARTED.md:

markdown
- [ ] Install `mcporter >= 0.8.1`: `npm install -g mcporter`

From package.json:

json
"peerDependencies": {
  "mcporter": ">=0.8.1"
},

Technical Analysis

The installation instructions resolve a mutable package version from the configured package registry and install it globally. The dependency constraint only specifies a lower bound, so future versions are accepted without review. No lockfile, exact version, package integrity value, or artifact verification procedure is provided.

Package installation can execute package lifecycle scripts. A globally installed CLI also becomes available broadly in the user's execution environment. In this project, mcporter receives access to a token-bearing DingTalk MCP configuration and processes business records, increasing the consequences of a malicious or compromised dependency release.

This finding does not establish that the current mcporter package is malicious. The risk arises from installing an unpinned, mutable third-party release into a privileged location and subsequently entrusting it with sensitive credentials and data.

Attack Path

  1. An attacker compromises the dependency publisher, package registry account, distribution channel, or a future dependency release.
  2. A malicious or compromised mcporter version is published under the expected package name.
  3. A user follows the documented npm install -g mcporter or bun install -g mcporter instruction.
  4. The package manager resolves the latest compatible release because no exact version is required ...[truncated 1102 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin mcporter to an exact reviewed version in both documentation and metadata:

    bash
    npm install --save-exact mcporter@0.8.1
    
    json
    "dependencies": {
      "mcporter": "0.8.1"
    }
    
  2. Commit a package lockfile containing resolved dependency versions and integrity hashes.

  3. Prefer a project-local installation over a global installation, then invoke the pinned binary through a controlled package script.

  4. Do not recommend sudo npm install -g. Installation and execution should use the minimum required user privileges.

  5. Document the expected package registry and publisher identity. Verify package provenance, signatures, or checksums where available.

  6. Review release notes and dependency changes before updating the pinned version. Apply updates through an explicit, tested dependency-review process rather than accepting every future release.

  7. Limit the CLI's environment and file access. Provide the MCP credential only when required, and run imports from a dedicated workspace with least-privilege DingTalk permissions.

  8. Add automated dependency scanning and provenance checks to the release process.

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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (34)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个用于钉钉 AI 表格数据层操作的技能,核心能力应是对 Base、Table、Field、Record 进行读写管理。但实际代码只做 MCP schema 兼容性检查:读取 DINGTALK_MCP_URL、调用 mcporter list dingtalk-ai-table --schema、基于关键字判断新旧 schema,并在工作区缓存检查结果。它不包含任何创建表、搜索表、读取表结构详情、增删改记录、字段管理或模板建表逻辑。虽然 schema 检查可能是相关配套步骤,但就该代码块本身而言,其主要目的与声明的核心用途明显不一致,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个具备实际业务操作能力的钉钉 AI 表格技能,但代码块仅包含触发词测试样例和基础单元测试框架。它不会访问钉钉资源、不会连接 MCP 服务,也不会执行任何 CRUD 或表结构管理操作。其主要目的与声明的功能性描述存在明显偏差:代码是测试/验证触发场景,而不是实现所宣称的表格操作能力。因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · CHANGELOG.md (reported line 179)May include surrounding context.

md
def test_path_traversal_attack(self):
        with self.assertRaises(ValueError):
            bulk_add_fields.resolve_safe_path('../etc/passwd', str(self.test_dir))

    def test_absolute_path_outside_root(self):
        with self.assertRaises(ValueError):

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · test_security.py (reported line 57)May include surrounding context.

python
def test_path_traversal_attack(self):
        with self.assertRaises(ValueError):
            bulk_add_fields.resolve_safe_path('../etc/passwd', str(self.test_dir))

    def test_absolute_path_outside_root(self):
        with self.assertRaises(ValueError):

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · test_security.py (reported line 61)May include surrounding context.

python
def test_path_traversal_attack(self):
        with self.assertRaises(ValueError):
            bulk_add_fields.resolve_safe_path('../etc/passwd', str(self.test_dir))

    def test_absolute_path_outside_root(self):
        with self.assertRaises(ValueError):

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file contains user-facing natural-language strings in Chinese, including the descriptive comment and runtime messages. This imposes a specific language on users without any opt-in or indication that the skill is intended only for a Chinese-speaking or region-specific context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The benchmark presents bulk import and automatic handling of record updates as a simple one-shot action without any caution that it will modify live data. In a skill specifically designed to create, update, and delete DingTalk table records, this omission can mislead users into triggering destructive or irreversible state changes without adequate confirmation or staging.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Describing Base creation and schema initialization as a one-step efficiency gain without noting that it creates new resources and changes schema can encourage users to run state-changing actions casually. In this skill's context, schema and base creation may affect production workflows, downstream automations, and data governance, so the missing warning materially increases risk of accidental changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The benchmark combines querying and updating records but does not distinguish read-only actions from writes or warn that record contents may be modified. Because this skill operates directly against DingTalk AI tables, users may assume the workflow is harmless like a search operation and unintentionally overwrite records in real systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The guide provides direct create, update, and delete examples against a live DingTalk table without any caution that these commands modify real data and may be irreversible. In an operational data-management skill, this increases the chance of accidental destructive actions by users who follow copy-paste examples against production bases.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The entire skill scoring document is written exclusively in Chinese and does not indicate that language selection is optional or limited to a justified region-specific use case. Under the policy rule for language/locale constraints, this can constitute a natural-language policy violation because it implicitly forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

Scanner excerpt · SCORING.md (reported line 135)May include surrounding context.

1. 文档完整性检查

bash
ls -la /Users/marila/skills/dingtalk-ai-table/
# 应包含:GETTING_STARTED.md, examples/, scripts/check-schema.sh

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

Scanner excerpt · SCORING.md (reported line 141)May include surrounding context.

1. 文档完整性检查

bash
ls -la /Users/marila/skills/dingtalk-ai-table/
# 应包含:GETTING_STARTED.md, examples/, scripts/check-schema.sh

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill explicitly requires environment variables, shell execution, and workspace file access, yet it declares no permission or allowed-tool scope. This weakens least-privilege controls and makes it easier for an agent to invoke filesystem and shell operations beyond what a user may reasonably expect from a spreadsheet skill.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill advertises broad automation scenarios without clear trigger boundaries or exclusions, while also exposing create, update, delete, and file-upload workflows. In an agent setting, vague scope increases the chance of the skill being selected for unintended tasks, leading to overbroad data access or destructive operations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation presents destructive and bulk-write capabilities, including delete and mass record operations, but does not require explicit confirmation, dry-run, or rollback guidance. In an autonomous or semi-autonomous workflow, this can cause accidental large-scale modification or deletion of business data.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

The skill instructs uploading a local file to an externally supplied uploadUrl using curl. Even though this is a legitimate attachment workflow, it still creates a data-exfiltration path if the URL is untrusted, substituted, or used without validating destination expectations; the context makes this more sensitive because the same document notes the URL carries access tokens and attachment content may be business data.

Content

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

md
--args '{"baseId":"base_xxx","fileName":"report.pdf","size":102400,"mimeType":"application/pdf"}'

# Step 2:把文件 PUT 到 uploadUrl(必须带 Content-Type,值必须与 mimeType 完全一致)
curl -X PUT "<uploadUrl>" \
  -H "Content-Type: application/pdf" \
  --data-binary @report.pdf

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file documents deletion capabilities such as delete_table with only operational notes, while providing no explicit user warning to confirm intent or highlight potential data loss before use. Under the markdown-specific warning rule, skills that describe data-affecting behavior should clearly disclose risks to user data and system integrity, especially when presenting actionable API usage guidance.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The delete_records section states that records can be batch deleted, but unlike other high-risk sections it does not warn that the action may permanently remove user data. Because this markdown serves as operational guidance, omission of a clear deletion warning can lead to unsafe use affecting data integrity.

Content

No source excerpt is available for this finding.

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 · api-reference.md (reported line 415)May include surrounding context.

md
--args '{"baseId":"base_xxx","fileName":"report.pdf","size":102400,"mimeType":"application/pdf"}'

# 2. PUT 文件到 uploadUrl(Content-Type 必须与 mimeType 完全一致)
curl -X PUT "<uploadUrl>" \
  -H "Content-Type: application/pdf" \
  --data-binary @report.pdf

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · bulk_add_fields.py (reported line 186)May include surrounding context.

python
cmd = build_mcporter_call(args)
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
        if result.returncode != 0:
            print(f"错误:{result.stderr.strip()}")
            return None

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring and later user-facing outputs are entirely in Chinese, which imposes a specific language on all users. The file does not offer any language selection, fallback, or explanation that this skill is intentionally region-specific.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · bulk_add_fields.py (reported line 91)May include surrounding context.

python
def get_mcporter_version() -> Optional[Tuple[int, int, int]]:
    for cmd in (['mcporter', '--version'], ['mcporter', 'version']):
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
        except (subprocess.TimeoutExpired, FileNotFoundError):
            return None

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · import_records.py (reported line 79)May include surrounding context.

python
def get_mcporter_version() -> Optional[Tuple[int, int, int]]:
    for cmd in (['mcporter', '--version'], ['mcporter', 'version']):
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
        except (subprocess.TimeoutExpired, FileNotFoundError):
            return None

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · import_records.py (reported line 178)May include surrounding context.

python
return None
    cmd = build_mcporter_call(args)
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
        if result.returncode != 0:
            print(f"错误:{result.stderr.strip()}")
            return None

Static analysis

No suspicious patterns detected.