Back to skill

Security audit

Dingtalk Ai Web Search

Security checks for vulnerabilities and agentic risk

Overview

This web-search skill is coherent, but it can permanently save and reuse any provided search-server URL, so future searches may be sent to an unexpected service.

Install only if you trust the MCP configuration source and understand that searches will be sent to the saved endpoint. Prefer a version that restricts the URL to the documented DingTalk HTTPS gateway, validates count values, and clearly warns before saving or replacing the endpoint.

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
scripts/search.sh:322
Finding

Persistent Arbitrary MCP Endpoint Enables Server-Side Request Forgery and Query Disclosure

Content
View full analysis
"$CONFIG_FILE" || die "写入配置文件失败,请检查文件权限($CONFIG_FILE)" } ``` ```bash # scripts/search.sh:113-137 mcp_post() { local url="$1" body="$2" sid="${3:-}" local hdr_file ct resp hdr_file=$(mktemp) || die "无法创建临时文件" local -a cmd=( curl -s -S -m 30 --connect-timeout 10 -X POST -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -D "$hdr_file" --data-raw "$body" ) [[ -n "$sid" ]] && cmd+=(-H "Mcp-Session-Id: $sid") cmd+=("$url") if ! resp=$("${cmd[@]}" 2>&1); then rm -f "$hdr_file" die "$resp" fi ``` ```bash # scripts/search.sh:322-327 if $ARG_SAVE; then [[ -z "$ARG_CONFIG" ]] && die "--save 需要配合 -c 传入 MCP JSON 配置" local MCP_URL MCP_URL=$(parse_mcp_url "$ARG_CONFIG") echo "正在检测连通性..." cmd_ping "$MCP_URL" save_url "$MCP_URL" ``` ### Technical Analysis The `--save` workflow extracts a URL from caller-provided JSON, contacts that URL, and then persists it in `scripts/.mcp_url`. The URL is not constrained by an HTTPS requirement, an approved-host allowlist, a permitted-port policy, or destination IP checks. Consequently, the script can be made to issue HTTP requests to an attacker-controlled endpoint or to services reachable from the Agent's network environment, including loopback and private network addresses. The URL is passed safely as one shell-array element, so this is not shell command injection; the vulnerability is the absence of network destination validation. The connectivit ...[truncated 2171 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/search.sh:197
Finding

Unvalidated Count Parameter Permits JSON-RPC Structure Injection

Content
View full analysis
Remediation
View remediation
= 1 && ARG_COUNT <= 50 )) \ || die "--count must be between 1 and 50" ``` 2. Reject missing option values before reading `$2`, producing a controlled validation error rather than relying on `set -u`. 3. Do not construct JSON by string concatenation. Build the complete request with `jq`: ```bash call_body=$( jq -cn \ --arg q "$query" \ --argjson count "$count" \ --arg freshness "$fv" \ '{ jsonrpc: "2.0", id: 3, method: "tools/call", params: { name: "web_search", arguments: ({q: $q, count: $count} + if $freshness == "" then {} else {freshness: $freshness} end) } }' ) ``` 4. If `jq` is unavailable, use Python's `json.dumps` or another structured JSON serializer rather than a text-based fallback. 5. Validate the final request as JSON before transmission and reject duplicate or unexpected fields. 6. Verify through `tools/list` that only the intended `web_search` operation is used by this Skill. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill instructs the agent to execute shell commands (bash .../scripts/search.sh) but does not declare any permissions or allowed-tools scope. This creates a least-privilege violation: a caller or platform reviewer cannot tell from metadata that shell execution is required, increasing the chance of unintended code execution or unsafe deployment in broader contexts.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The description contains broad trigger phrases like “搜一下”, “帮我查”, “查资料”, and “web search”, which are common in everyday conversation and can cause the skill to activate unexpectedly. In this skill, accidental activation is more sensitive because it can lead to shell execution and external network requests, including prompting users for MCP configuration.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation tells the agent to collect MCP configuration JSON from the user and use it to connect to an external DingTalk MCP service, but it does not clearly warn that both search queries and provided configuration data will be sent to external services and may be stored. This is a privacy and data-handling issue that can expose sensitive queries, internal endpoints, or tokens embedded in configuration URLs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

User-facing comments, usage text, status messages, and formatted output are written in Chinese, and the script does not offer an option to select another language. This creates a language/locale policy concern because the skill imposes a specific language on all users without explicit opt-in or documented justification.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · scripts/search.sh (reported line 99)May include surrounding context.

sh
hdr_file=$(mktemp) || die "无法创建临时文件"

  local -a cmd=(
    curl -s -S -m 30 --connect-timeout 10
    -X POST
    -H 'Content-Type: application/json'
    -H 'Accept: application/json, text/event-stream'

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · scripts/search.sh (reported line 136)May include surrounding context.

sh
local hdr_file
  hdr_file=$(mktemp) || die "无法创建临时文件"

  curl -s -S -m 30 --connect-timeout 10 \
    -X POST \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json, text/event-stream' \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script sends the user's query and request payload to the configured MCP URL via HTTP POST, which may disclose user-provided search terms to an external service. Although the file contains implementation comments, it does not present a user-facing warning, confirmation, or runtime notice that search content will be transmitted off-host.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The --save flow persists the MCP URL to a local file adjacent to the script, affecting the user's filesystem state beyond the current invocation. While this behavior is partly implied by the option name and comments, there is no explicit warning in the interface about the exact storage location or persistence implications before the write occurs.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.