Back to skill

Security audit

Dingtalk Workspace

Security checks for vulnerabilities and agentic risk

Overview

This DingTalk automation skill is mostly coherent, but it should go to Review because it includes unsafe installer commands and examples/scripts that can approve or mutate enterprise data without a strong confirmation boundary.

Review this before installing in a real enterprise workspace. Prefer a verified release or pinned source build, avoid the pipe-to-shell installer examples, use least-privilege DingTalk OAuth credentials, do not put real client secrets in shell history or shared logs, and require human review before approvals, deletes, bulk imports, group changes, or message sends. Treat bundled scripts as applying changes by default unless you explicitly use dry-run behavior.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:42
Finding

Unverified Remote Installer Is Executed Directly from a Mutable Branch

Content
View full analysis
Remediation
View remediation
install.sh" | sha256sum --check - ``` 5. Require users to inspect the locally downloaded script before explicitly running it: ```bash less install.sh sh install.sh ``` 6. Prefer reproducible builds from a pinned source tag or signed release artifacts. 7. Document the expected files, network endpoints, and filesystem changes made by the installer. 8. Avoid recommending elevated execution unless a specific operation strictly requires it. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/products/oa.md:82
Finding

Approval Workflow Authorizes Expenses Using Only Attacker-Influenced Title Text

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/calendar_schedule_meeting.py:27
Finding

Mutation Scripts Skip Confirmation and Execute Bulk Changes by Default

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:54
Finding

OAuth Client Secrets Are Passed Through Command-Line Arguments

Content
View full analysis
--client-secret # Or via environment variables export DWS_CLIENT_ID= export DWS_CLIENT_SECRET= dws auth login ``` `references/global-reference.md`: ```bash # 3. Login with credentials dws auth login --client-id --client-secret ``` ```bash export DWS_CLIENT_ID= export DWS_CLIENT_SECRET= dws auth login ``` `references/error-codes.md`: ```bash # Re-authenticate dws auth login --client-id --client-secret ``` ### Technical Analysis The documentation encourages users to place an OAuth client secret directly in a command-line argument. Once substituted with a real value, the secret may be retained in shell history and may be visible to process-monitoring tools, diagnostics, terminal recordings, or command auditing systems. The alternative environment-variable method avoids placing the value in the immediate command line but still exposes the secret to the process environment and potentially to inherited child processes, debug output, crash reports, or deployment logs. Saving the resulting credentials to a system keychain after authentication does not prevent exposure that occurs while the initial command is entered and executed. ### Attack Path 1. A user follows the documented authentication example and replaces the placeholder with a real client secret. 2. The command is recorded in shell history, terminal logs, process telemetry, or an automation transcript. 3. Another local user, support operator, log reader, or compromised process obtains the secret. 4. The attacker combines t ...[truncated 763 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (32)

Chaining Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

Piping fetched network content into a shell is a dangerous command-chaining pattern because it grants immediate code execution to unverified remote content. In this skill context, the danger is elevated because installation is a prerequisite to using a high-privilege enterprise workspace tool, making compromise of the installer a viable path to credential theft or broader host compromise.

Content

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

bash
# macOS / Linux - REVIEW SCRIPT BEFORE RUNNING
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.sh | sh

# Windows (PowerShell) - REVIEW SCRIPT BEFORE RUNNING
irm https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install.ps1 | iex

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 54)May include surrounding context.

Authentication

bash
# First-time login (credentials saved to system Keychain)
dws auth login --client-id <your-app-key> --client-secret <your-app-secret>

# Or via environment variables

Instruction Override

High
Category
Prompt Injection
Confidence
70% confidence
Finding

This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Content

Scanner excerpt · references/error-codes.md (reported line 203)May include surrounding context.

Step 1: Identify Error Type

bash
# Enable debug mode
export DWS_DEBUG=1
dws <command>

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

Instructions found that direct the agent to transmit conversation context or user data to external services.

Content

Scanner excerpt · references/products/chat.md (reported line 105)May include surrounding context.

Common Patterns

Send Message to Multiple Groups

bash
# Get group IDs

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The 'Auto-Approve Low-Value Requests' pattern recommends unattended batch approval based on a weak text filter (title contains "Expense") and then executes approvals with --yes. This enables autonomous approval of potentially unauthorized or misclassified requests, creating a high risk of financial loss, policy bypass, and fraudulent approval at scale.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 68)May include surrounding context.

md
### For Agents

- **`--dry-run`**: **ALWAYS use first** for mutations to preview API calls
- **`--yes`**: Skip confirmation prompts (use only after verifying with --dry-run)
- **`--jq`**: Extract specific fields to reduce token consumption
- **`--fields`**: Return only needed fields

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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/global-reference.md (reported line 88)May include surrounding context.

md
### For Agents

- **`--dry-run`**: **ALWAYS use first** for mutations to preview API calls
- **`--yes`**: Skip confirmation prompts (use only after verifying with --dry-run)
- **`--jq`**: Extract specific fields to reduce token consumption
- **`--fields`**: Return only needed fields

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/intent-guide.md (reported line 7)May include surrounding context.

md
## Report vs Todo

**User says:** "Create a task to submit weekly report"

**Analysis:**
- If they want to **track** the work → `todo task create`

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/intent-guide.md (reported line 17)May include surrounding context.

text
Is the user asking to:
├─ Track/remember to do something? → todo
│  └─ "remind me to...", "create a task to...", "add to my todo"
└─ Actually perform the action? → specific product
   └─ "submit a report" → report create
   └─ "send a message" → chat message send

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file describes a delete operation for records, which can affect user data, but it provides no warning that the action is destructive or potentially irreversible. Under the markdown-specific warning criteria, destructive behaviors should be disclosed so users understand the risk before use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Deleting a field can affect system integrity and may remove or invalidate associated table data, yet the documentation presents the command without any cautionary note. Markdown skill descriptions should warn users about operations that can materially alter or destroy data structures.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file includes examples for listing shift schedules, team summaries, and department-level attendance information, which can expose employee attendance data. The document provides no warning that these commands should only be used with appropriate authorization or that they may involve sensitive personnel data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file includes a Delete Event operation that removes calendar events, but the surrounding documentation provides no warning that the action is destructive or potentially irreversible. Under the markdown criteria for SQP-2, skills should disclose behaviors that can affect user data or system integrity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This markdown file documents dws chat message recall, which can remove a previously sent message, but it provides no warning that the action is destructive or potentially irreversible. Under the markdown-specific SQP-2 criteria, skills should disclose behaviors that could affect user data or system integrity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

The documentation includes group creation, member addition, and member removal commands, all of which affect collaboration state and user access, but it does not warn users about the impact of modifying memberships. For markdown files, SQP-2 requires warning users about actions that can affect data, privacy, or system integrity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation provides direct examples for approving and rejecting workflow items with the non-interactive --yes flag, but it does not warn that these actions may be irreversible or require human verification. In an agent or automation context, this lowers friction for unsafe execution and can lead to unauthorized or mistaken business decisions being committed immediately.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
94% confidence
Finding

The section explicitly promotes autonomous decision making for approvals, which is sensitive because approvals are control points for finance, access, or operational changes. In this skill context, encouraging automatic decisions without oversight is especially dangerous because the command directly changes business workflow state.

Content

Scanner excerpt · references/products/oa.md (reported line 82)May include surrounding context.

Common Patterns

Auto-Approve Low-Value Requests

bash
# Get pending approvals

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
95% confidence
Finding

The loop performs repeated approval actions automatically with dws oa approval approve ... --yes, which operationalizes autonomous decision making rather than merely describing it. This is dangerous because it can mass-approve pending items without individualized validation, amplifying the impact of bad logic, spoofed requests, or accidental execution.

Content

Scanner excerpt · references/products/oa.md (reported line 90)May include surrounding context.

Approve each

for inst in $INSTANCES; do dws oa approval approve --instance-id "$inst" --comment "Auto-approved" --yes done

text

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file documents a destructive operation, dws todo task delete --task-id <taskId>, but provides no warning that the action removes a task or may be irreversible. Under the markdown-file criteria for missing user warnings, destructive behaviors that could affect user data should be accompanied by a clear disclosure or caution.

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 · scripts/calendar_free_slot_finder.py (reported line 19)May include surrounding context.

python
def run_dws(args):
    """Run dws command and return JSON output."""
    cmd = ["dws"] + args
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"Error: {result.stderr}", file=sys.stderr)
        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 · scripts/calendar_schedule_meeting.py (reported line 19)May include surrounding context.

python
def run_dws(args):
    """Run dws command and return JSON output."""
    cmd = ["dws"] + args
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"Error: {result.stderr}", file=sys.stderr)
        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 · scripts/calendar_schedule_meeting.py (reported line 36)May include surrounding context.

python
def run_dws(args):
    """Run dws command and return JSON output."""
    cmd = ["dws"] + args
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"Error: {result.stderr}", file=sys.stderr)
        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 · scripts/contact_dept_members.py (reported line 18)May include surrounding context.

python
def run_dws(args):
    """Run dws command and return JSON output."""
    cmd = ["dws"] + args
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"Error: {result.stderr}", file=sys.stderr)
        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 · scripts/import_records.py (reported line 19)May include surrounding context.

python
def run_dws(args):
    """Run dws command and return JSON output."""
    cmd = ["dws"] + args
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"Error: {result.stderr}", file=sys.stderr)
        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 · scripts/report_inbox_today.py (reported line 19)May include surrounding context.

python
def run_dws(args):
    """Run dws command and return JSON output."""
    cmd = ["dws"] + args
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"Error: {result.stderr}", file=sys.stderr)
        return None