Back to skill

Security audit

禅道-ZenTao

Security checks for vulnerabilities and agentic risk

Overview

This ZenTao integration is mostly purpose-aligned, but it handles credentials and project-management mutations with enough insecure transport and scoping risk that users should review it carefully before installing.

Install only if you understand that this skill will use credentials from TOOLS.md to access your ZenTao server and may perform high-impact changes with your account's permissions. Use an HTTPS-only ZenTao URL, prefer a least-privilege service account, avoid committing TOOLS.md, and require explicit confirmation before any create, update, delete, review, or test-run action.

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

T09 · Insecure Skill Coding Practices

Error
Location
lib/zentao_client.py:34
Finding

ZenTao credentials can be transmitted over plaintext HTTP

Content
View full analysis
Optional[str]: """REST API: Get Token""" try: url = f"{self.rest_api_base}/tokens" data = {'account': self.username, 'password': self.password} response = httpx.post(url, json=data, timeout=30) ``` The REST client contains the equivalent implementation: ```python def get_token(self) -> Optional[str]: """POST /tokens - Get Token""" url = f"{self.base_url}/tokens" data = {'account': self.username, 'password': self.password} try: response = httpx.post(url, json=data, timeout=30) ``` The documented configuration explicitly recommends an HTTP URL: ```markdown - **API URL:** http:/// - **Username:** - **Password:** ``` ### Technical Analysis The endpoint is read from the credential configuration and used without validating its scheme. Both API clients submit the ZenTao username and password directly to the resulting `/tokens` endpoint. The legacy authentication implementation also submits the password to the configured endpoint. If the endpoint begins with `http://`, neither `httpx` nor `requests` provides transport encryption. The password, username, session identifiers, authentication token, API requests, and returned project-management data can consequently be observed or modified by any attacker able to intercept the connection. This behavior is directly encouraged by the examples in `SKILL.md` and `package.json`. Network communication is necessary for the declared ZenTao integration, but supporting plaintext credential transport without a warning or explicit opt-in ...[truncated 1430 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
lib/zentao_rest_client.py:482
Finding

Authentication tokens and session identifiers can leak through output and URLs

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:4
Finding

Dependency manifests are incomplete and use unbounded version ranges

Content
View full analysis
=2.28.0 beautifulsoup4>=4.11.0 ``` The package metadata similarly omits exact versions: ```json "dependencies": { "python": ">=3.8", "packages": ["requests", "beautifulsoup4"] } ``` However, both clients import `httpx`, which is not declared: ```python import requests import httpx ``` ```python import httpx ``` ### Technical Analysis Open-ended dependency constraints allow installations at different times to resolve materially different package versions, including future releases that have not been reviewed with this Skill. No lock file or package hashes are present to verify the exact artifacts installed. The required `httpx` package is absent from both dependency declarations. A standard installation can therefore fail at import time. Users may respond by manually installing an arbitrary version from the package index, further reducing reproducibility and bypassing any intended dependency review. `beautifulsoup4` appears in the manifests but was not observed in the reviewed source imports, which unnecessarily increases dependency surface if it is installed solely for this package. ### Attack Path 1. A user installs the Skill dependencies using `pip install -r requirements.txt`. 2. The resolver selects the newest releases satisfying the open-ended constraints rather than a reviewed dependency set. 3. The application fails because `httpx` is missing, prompting the user or automation to install an unspecified version manually. 4. A compromised, vulnerable, or unexpectedly incompatible future release is installed and imported into the Sk ...[truncated 894 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (30)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 99)May include surrounding context.

python
return self._request('PUT', f'/users/{user_id}', data=data)
    
    def delete_user(self, user_id: int) -> Tuple[bool, Any]:
        """DELETE /users/{id} - 删除用户"""
        return self._request('DELETE', f'/users/{user_id}')
    
    # ==================== 项目集 Program ====================

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 121)May include surrounding context.

python
return self._request('PUT', f'/programs/{program_id}', data=data)
    
    def delete_program(self, program_id: int) -> Tuple[bool, Any]:
        """DELETE /programs/{id} - 删除项目集"""
        return self._request('DELETE', f'/programs/{program_id}')
    
    # ==================== 产品 Product ====================

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 143)May include surrounding context.

python
return self._request('PUT', f'/products/{product_id}', data=data)
    
    def delete_product(self, product_id: int) -> Tuple[bool, Any]:
        """DELETE /products/{id} - 删除产品"""
        return self._request('DELETE', f'/products/{product_id}')
    
    def get_product_teams(self, product_id: int) -> Tuple[bool, Any]:

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 169)May include surrounding context.

python
return self._request('PUT', f'/products/{product_id}/plans/{plan_id}', data=data)
    
    def delete_product_plan(self, product_id: int, plan_id: int) -> Tuple[bool, Any]:
        """DELETE /products/{id}/plans/{planID} - 删除产品计划"""
        return self._request('DELETE', f'/products/{product_id}/plans/{plan_id}')
    
    # ==================== 发布 Release ====================

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 201)May include surrounding context.

python
return self._request('PUT', f'/products/{product_id}/stories/{story_id}', data=data)
    
    def delete_story(self, product_id: int, story_id: int) -> Tuple[bool, Any]:
        """DELETE /products/{id}/stories/{storyID} - 删除需求"""
        return self._request('DELETE', f'/products/{product_id}/stories/{story_id}')
    
    def activate_story(self, product_id: int, story_id: int) -> Tuple[bool, Any]:

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 243)May include surrounding context.

python
return self._request('PUT', f'/projects/{project_id}', data=data)
    
    def delete_project(self, project_id: int) -> Tuple[bool, Any]:
        """DELETE /projects/{id} - 删除项目"""
        return self._request('DELETE', f'/projects/{project_id}')
    
    # ==================== 版本 Build ====================

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 261)May include surrounding context.

python
return self._request('PUT', f'/builds/{build_id}', data=data)
    
    def delete_build(self, build_id: int) -> Tuple[bool, Any]:
        """DELETE /builds/{id} - 删除版本"""
        return self._request('DELETE', f'/builds/{build_id}')
    
    # ==================== 执行 Execution ====================

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 295)May include surrounding context.

python
return self._request('PUT', f'/executions/{execution_id}', data=data)
    
    def delete_execution(self, execution_id: int) -> Tuple[bool, Any]:
        """DELETE /executions/{id} - 删除执行"""
        return self._request('DELETE', f'/executions/{execution_id}')
    
    # ==================== 任务 Task ====================

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 317)May include surrounding context.

python
return self._request('PUT', f'/tasks/{task_id}', data=data)
    
    def delete_task(self, task_id: int) -> Tuple[bool, Any]:
        """DELETE /tasks/{id} - 删除任务"""
        return self._request('DELETE', f'/tasks/{task_id}')
    
    # ==================== 缺陷 Bug ====================

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 339)May include surrounding context.

python
return self._request('PUT', f'/bugs/{bug_id}', data=data)
    
    def delete_bug(self, bug_id: int) -> Tuple[bool, Any]:
        """DELETE /bugs/{id} - 删除 Bug"""
        return self._request('DELETE', f'/bugs/{bug_id}')
    
    # ==================== 用例 TestCase ====================

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 361)May include surrounding context.

python
return self._request('PUT', f'/testcases/{case_id}', data=data)
    
    def delete_test_case(self, case_id: int) -> Tuple[bool, Any]:
        """DELETE /testcases/{id} - 删除用例"""
        return self._request('DELETE', f'/testcases/{case_id}')
    
    # ==================== 测试单 TestTask ====================

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 401)May include surrounding context.

python
return self._request('PUT', f'/feedbacks/{feedback_id}', data=data)
    
    def delete_feedback(self, feedback_id: int) -> Tuple[bool, Any]:
        """DELETE /feedbacks/{id} - 删除反馈"""
        return self._request('DELETE', f'/feedbacks/{feedback_id}')
    
    # ==================== 工单 Ticket ====================

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · lib/zentao_rest_client.py (reported line 423)May include surrounding context.

python
return self._request('PUT', f'/tickets/{ticket_id}', data=data)
    
    def delete_ticket(self, ticket_id: int) -> Tuple[bool, Any]:
        """DELETE /tickets/{id} - 删除工单"""
        return self._request('DELETE', f'/tickets/{ticket_id}')

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger list includes generic terms such as 'project management' and broad product names that can overlap with ordinary user requests, causing the skill to activate in contexts where the user did not clearly intend to use this integration. Because the skill reads credentials and can access organizational project data, overbroad activation increases the chance of unintended data exposure or execution of sensitive queries.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
87% confidence
Finding

The skill explicitly allows many query operations with no confirmation, including user, product, project, task, and bug retrieval. In a credentialed enterprise integration, that creates an autonomous data-access path where ambiguous or accidental invocation could disclose potentially sensitive organizational metadata without a deliberate confirmation step.

Content

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

md
### Features

#### Query Operations (No Confirmation Required)

**User**
- Get user list

Tainted flow: 'data' from requests.get (line 259, network input) → httpx.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · lib/zentao_client.py (reported line 97)May include surrounding context.

python
if method.upper() == 'GET':
                response = httpx.get(url, headers=headers, timeout=30)
            elif method.upper() == 'POST':
                response = httpx.post(url, headers=headers, json=data, timeout=30)
            else:
                return False, f"不支持的方法:{method}"

Tainted flow: 'data' from requests.get (line 259, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · lib/zentao_client.py (reported line 126)May include surrounding context.

python
if method.upper() == 'GET':
                response = requests.get(url, timeout=30)
            elif method.upper() == 'POST':
                response = requests.post(url, data=data, timeout=30)
            else:
                return False, f"不支持的方法:{method}"

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This client implements multiple write-capable operations against ZenTao, including creating stories, tasks, release plans, approving stories, and running test cases. In a skill context with no declared guardrails, approval workflow, or purpose limitation, these methods enable unauthorized or unintended mutation of project-management data if the skill is invoked with available credentials.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code automatically reads ZenTao endpoint and plaintext credentials from a local TOOLS.md file in the user's workspace, which is a sensitive local secret source unrelated to secure credential handling. In an agent-skill context, this is dangerous because it silently harvests credentials from disk and can then use them to access remote systems without explicit user approval at runtime.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The function reads credentials from a local TOOLS.md path without any user-facing warning, consent prompt, or disclosure that secrets will be accessed from disk. In an agent environment, undisclosed secret access is a significant trust and privacy violation because users may not expect a skill to inspect local files for reusable credentials.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The get_token method sends the configured username and password to the remote ZenTao API using an HTTP POST request. The file contains no user-facing warning, confirmation, or clear disclosure that local credentials will be transmitted to the configured endpoint.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The module automatically reads ZenTao endpoint and credentials from a local TOOLS.md file in the user's workspace, which is a sensitive file access behavior beyond the core necessity of a generic REST client. In an agent/skill context, this enables implicit secret harvesting and use of credentials without explicit user consent at call time, increasing the risk of credential misuse or unexpected data access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code reads stored credentials from a local TOOLS.md file without any user-facing disclosure, confirmation, or consent flow. In a skill environment, silently consuming secrets from a user workspace is dangerous because users may not realize the skill is capable of discovering and using credentials automatically.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file’s natural-language interface begins by declaring the tool in Chinese, and the rest of the user-facing prompts and help text are likewise fixed to Chinese. That enforces a specific language/locale for all users without any visible option to choose another language, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The create_task path requires params ['execution_id', 'story_id', 'name', 'assign_to'], but parse_args does not extract a 'name' field and the usage text tells users to supply 标题=xxx instead. This is an active contradiction between the documented CLI intent and the implemented parameter handling, causing the advertised command to fail even when used as shown.

Content

No source excerpt is available for this finding.