Back to skill

Security audit

Dida Coach

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Dida task-coaching skill, but it needs review because it can make live task changes through broad implicit triggers and stores OAuth credentials in local files without strong safeguards.

Install only if you are comfortable giving the skill read/write access to your Dida365 tasks. Prefer the normal MCP Connect/Authorize flow over the optional local OAuth helper; if you use local OAuth, treat ~/.dida-coach/dida-openapi.env as a sensitive secrets file, restrict its permissions, and rotate/delete credentials if exposed. Review task changes before letting broad natural-language requests create, move, complete, or reschedule tasks.

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

Warning
Location
tools/openapi_auth.py:114
Finding

OAuth credentials are persisted without restrictive file permissions

Content
View full analysis

Vulnerability Details

File Location: tools/openapi_auth.py:114-145
Vulnerability Type: Plaintext credential storage with insufficient permission enforcement
Risk Level: Medium

Vulnerable Code:

python
def write_openapi_env(
    client_id: str,
    client_secret: str,
    token_data: Dict[str, object],
    *,
    redirect_uri: str = DEFAULT_REDIRECT_URI,
    path: Optional[Path] = None,
) -> Path:
    """Write Open API credentials to a local .env file."""

    env_path = path or get_openapi_env_path()
    current = read_openapi_env(env_path)
    current.update(
        {
            "DIDA_OPENAPI_CLIENT_ID": client_id,
            "DIDA_OPENAPI_CLIENT_SECRET": client_secret,
            "DIDA_OPENAPI_REDIRECT_URI": redirect_uri,
            "DIDA_OPENAPI_ACCESS_TOKEN": str(token_data.get("access_token", "")),
            "DIDA_OPENAPI_REFRESH_TOKEN": str(token_data.get("refresh_token", "")),
            "DIDA_OPENAPI_TOKEN_TYPE": str(token_data.get("token_type", "")),
            "DIDA_OPENAPI_SCOPE": str(token_data.get("scope", DEFAULT_SCOPE)),
        }
    )
    if "expires_in" in token_data:
        current["DIDA_OPENAPI_EXPIRES_IN"] = str(token_data.get("expires_in", ""))

    lines = ["# Dida Coach Open API credentials"]
    for key in sorted(current.keys()):
        lines.append(f"{key}={current[key]}")
    env_path.parent.mkdir(parents=True, exist_ok=True)
    env_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
    return env_path

Technical Analysis

The function stores the OAuth client secret, access token, and refresh token as plaintext in ~/.dida-coach/dida-openapi.env. It writes the file using Path.write_text() without explicitly creating it with owner-only permissions or correcting the permissions of an existing file.

The resulting permissions depend on the process umask. With a common umask such as 022, a newly created cr ...[truncated 1666 chars]

Remediation
View remediation

Remediation Suggestions

  • Create the credential file atomically with owner-only mode 0600, rather than relying on the process umask.
  • Explicitly apply chmod(0o600) after creation and when updating an existing file.
  • Ensure the parent credential directory is restricted to mode 0700.
  • Use a temporary file in the same directory, set restrictive permissions before writing, flush and synchronize it, and atomically replace the destination to prevent partial writes.
  • Prefer an operating-system credential store or keychain for client secrets and refresh tokens.
  • Store only credentials required for subsequent operations and avoid retaining the client secret if it is unnecessary after authorization.
  • Document that the credential file contains sensitive values and must never be committed, shared, or included in diagnostic output.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/dida_openapi_oauth.py:20
Finding

OAuth client secret is accepted through a command-line argument

Content
View full analysis

Vulnerability Details

File Location: scripts/dida_openapi_oauth.py:20-23
Additional Locations: references/openapi-auth-setup.md:21-27, prompts/setup.md:71-77, README.md:187-191
Vulnerability Type: Sensitive information exposure through process arguments and shell history
Risk Level: Low

Vulnerable Code:

python
parser = argparse.ArgumentParser(description="Complete Dida Open API OAuth authorization")
parser.add_argument("--client-id", required=True)
parser.add_argument("--client-secret", required=True)
parser.add_argument("--redirect-uri", default="http://localhost:38000/callback")
parser.add_argument("--scope", default="tasks:read tasks:write")
parser.add_argument("--open-browser", action="store_true")
args = parser.parse_args()

The documented invocation pattern is:

bash
python3 scripts/dida_openapi_oauth.py \
  --client-id YOUR_CLIENT_ID \
  --client-secret YOUR_CLIENT_SECRET \
  --open-browser

Technical Analysis

The helper requires the OAuth client secret to be provided as a command-line argument. When a user substitutes the actual secret, it may become visible through shell history, process-list inspection, command auditing, terminal logging, crash diagnostics, or automation telemetry.

Command-line arguments are generally not an appropriate channel for long-lived credentials because they may be observable beyond the lifetime and access boundaries intended by the user. The accompanying documentation reinforces this unsafe usage pattern.

Attack Path

  1. The user follows the documented command and replaces YOUR_CLIENT_SECRET with the real OAuth client secret.
  2. The shell records the command in its history, or the operating system exposes the active process arguments to another local user or monitoring component.
  3. An attacker with access to that history, process metadata, terminal log, or telemetry extracts the client secret.
  4. The attack ...[truncated 938 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove the required --client-secret command-line option.
  • Prompt interactively using getpass.getpass() so the secret is not echoed or included in process arguments.
  • For non-interactive use, accept a path to a credential file protected with mode 0600, or integrate with an operating-system credential store.
  • If environment-variable input is supported, clearly warn that environment variables may still be exposed by diagnostics or process inspection in some environments.
  • Update all README, prompt, and reference examples so they no longer instruct users to place real secrets directly on the command line.
  • Ensure errors and debug output never print the supplied secret or the generated HTTP Basic authorization value.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (63)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill description does not prominently communicate that it may listen for localhost OAuth callbacks, exchange authorization codes for tokens, and persist API credentials locally. Hidden credential-handling behavior is security-sensitive because it can expose secrets, normalize unsafe local storage, and create unexpected attack surface on the user machine.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill description does not prominently communicate that it may listen for localhost OAuth callbacks, exchange authorization codes for tokens, and persist API credentials locally. Hidden credential-handling behavior is security-sensitive because it can expose secrets, normalize unsafe local storage, and create unexpected attack surface on the user machine.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description does not prominently communicate that it may listen for localhost OAuth callbacks, exchange authorization codes for tokens, and persist API credentials locally. Hidden credential-handling behavior is security-sensitive because it can expose secrets, normalize unsafe local storage, and create unexpected attack surface on the user machine.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description does not prominently communicate that it may listen for localhost OAuth callbacks, exchange authorization codes for tokens, and persist API credentials locally. Hidden credential-handling behavior is security-sensitive because it can expose secrets, normalize unsafe local storage, and create unexpected attack surface on the user machine.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill description does not prominently communicate that it may listen for localhost OAuth callbacks, exchange authorization codes for tokens, and persist API credentials locally. Hidden credential-handling behavior is security-sensitive because it can expose secrets, normalize unsafe local storage, and create unexpected attack surface on the user machine.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill description does not prominently communicate that it may listen for localhost OAuth callbacks, exchange authorization codes for tokens, and persist API credentials locally. Hidden credential-handling behavior is security-sensitive because it can expose secrets, normalize unsafe local storage, and create unexpected attack surface on the user machine.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill describes automatically writing OAuth credentials to ~/.dida-coach/dida-openapi.env without an explicit warning that sensitive tokens or secrets will be stored on disk. Persisting credentials silently or without storage-safety guidance increases the risk of credential exposure through weak file permissions, backups, shell history, or later compromise of the host.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger pattern "(我想|我要|计划|目标).*" is extremely broad and can match ordinary conversation that is not an explicit request to invoke this skill. In a skill that can read and modify task data through the dida365 MCP, overbroad activation raises the risk of unintended task operations or disclosure of task information when the user did not intend to use this capability.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
94% confidence
Finding

This task-management trigger includes many ambiguous phrases such as "查一下" and broad listing/search verbs that can overlap with normal chat. Because the skill supports querying, creating, moving, and completing tasks, accidental invocation could expose task metadata or perform unintended modifications in the user's productivity system.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The timeboxing trigger based on generic verbs like "做|完成|准备|安排" is likely to match a large amount of ordinary language. In this skill's context, that can cause inappropriate creation of schedules or timeboxes, or route conversations into a workflow that may lead to downstream task writes without clear user intent.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The rescheduling trigger relies on highly generic verbs like "改|调整|延后|提前|取消", which appear in many unrelated conversations. In a skill with task-editing capabilities, such ambiguity creates a substantial risk of unintended deadline, reminder, or task-state modifications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The README promotes natural-language creation, movement, updating, and completion of remote tasks through MCP, including write-after-read validation, but it does not clearly warn that these actions modify live user data on a third-party service and may disclose task contents to a remote endpoint. Because this skill is specifically designed to manage real personal productivity data, lack of a privacy and integrity notice increases the risk of unintended changes, oversharing, or misuse under ambiguous prompts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README explicitly describes workflows that automatically write local MCP configuration and OAuth token material to user-controlled files such as ~/.openclaw/openclaw.json and ~/.dida-coach/dida-openapi.env, but it does not prominently warn about filesystem modification, credential persistence, or the need to review file permissions and contents before use. In a skill that users may trust and run quickly, this omission can lead to unintended credential exposure, unsafe config overwrites, or persistence of sensitive tokens on disk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares broad capabilities that include local file reads/writes, environment access, and networked OAuth/MCP setup flows, but it does not define any explicit tool scope or allowed-tools boundary. That increases the chance the agent can perform configuration changes or credential-related operations beyond what a user would reasonably infer from a 'task coach' skill.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases are broad everyday terms like planning, reminders, procrastination, and task lookup, making accidental activation plausible in unrelated conversations. In this skill, accidental activation is more concerning because the skill can lead to external task writes, local file operations, and setup/auth flows rather than only passive advice.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The intent-routing examples use broad and ambiguous conditions that can route normal conversational text into operational flows like task creation, rescheduling, or productivity-system changes. Because the skill includes write actions to external task systems and local state, ambiguous routing increases the chance of unintended modifications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill permits single write operations to execute by default and only reserves extra confirmation for 'high-risk batch actions,' without a strong user-facing warning that external task data may be modified. This is dangerous because seemingly casual chat requests can cause real changes in third-party task systems, especially when combined with broad triggers and ambiguous routing.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The user-facing description is written entirely in Chinese and presents the skill as operating in that language, while the file does not offer language selection or explain that the skill is intended only for a Chinese-speaking or region-specific context. This can violate language or locale policy where users should be able to opt in to a specific language.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill enables implicit invocation without any visible activation constraints, so the agent may auto-trigger this skill on broad productivity-related phrases and then gain read/write access to the linked Dida task system. In this context, that creates a real risk of unintended task queries or modifications, especially because the MCP dependency is capable of state-changing operations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This manifest contains user-facing natural-language labels such as '默认配置', '灵活番茄', and '经典番茄' exclusively in Chinese. The file does not indicate that the skill is region-specific or offer any language/locale opt-in, which can violate language policy requirements for user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The entire skill file is written only in Chinese and provides no indication that language choice is optional or that the skill is intentionally limited to a Chinese-speaking context. Under the policy rule, forcing a specific language without user opt-in or clear justification is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The entire persona specification is written only in Chinese and defines user-facing completion and coaching phrases exclusively in Chinese. This imposes a language choice on users without indicating that language selection is optional or that the skill is limited to a Chinese-speaking context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The entire persona definition and example output are written in Chinese, which indicates the skill is designed to operate in a specific language. There is no visible opt-in, alternative language option, or documentation that this is a region-specific skill, so it may violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown skill is written entirely in Chinese and defines the persona responses in Chinese, with no indication that the user can choose another language or that the skill is limited to Chinese-speaking contexts. That creates a language/locale policy concern because the skill appears to prescribe a specific language by default rather than offering user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The prompt is entirely written in Chinese and prescribes Chinese-language interaction without any indication that the user may choose another language. This can exclude or mislead users who operate in a different language, increasing the chance of misunderstanding task-review outputs or unintended edits to local productivity files.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.