Back to skill

Security audit

Long Task Manager

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated purpose, but its task file handling can escape the intended storage folder, so users should review it before installing.

Install only if you trust the callers that will pass task IDs and agent IDs, or first add strict identifier validation and path containment. Keep task_dir inside an approved workspace, avoid storing sensitive prompts or results in the task store, and use cleanup carefully because it deletes stored task directories.

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

T09 · Insecure Skill Coding Practices

Error
Location
lib/long_task_manager.py:110
Finding

Path Traversal Through Unvalidated Task and Agent Identifiers

Content
View full analysis

Vulnerability Details

File Location: lib/long_task_manager.py, lines 110–124; additional sinks at lines 151–164, 189–192, 204–209, 222–227, 300, and 344–345
Vulnerability Type: Unrestricted filesystem path construction / path traversal
Risk Level: High

Vulnerable Code

python
def _get_task_path(self, task_id: str) -> Path:
    """获取任务目录"""
    return self.task_dir / task_id

def _get_config_path(self, task_id: str) -> Path:
    """获取配置文件路径"""
    return self._get_task_path(task_id) / "config.json"

def _get_status_path(self, task_id: str) -> Path:
    """获取状态文件路径"""
    return self._get_task_path(task_id) / "status.json"

def _get_result_path(self, task_id: str) -> Path:
    """获取结果文件路径"""
    return self._get_task_path(task_id) / "result.json"

The unvalidated paths are used by submission and file-access operations:

python
# 生成任务ID
task_id = self._generate_task_id(agent_id)
task_path = self._get_task_path(task_id)
task_path.mkdir(parents=True, exist_ok=True)

# 保存配置
config = {
    "task_id": task_id,
    "agent_id": agent_id,
    "priority": priority,
    "config": task_config,
    "submitted_at": datetime.now().isoformat(),
    "status": TaskStatus.PENDING.value
}

with open(self._get_config_path(task_id), 'w', encoding='utf-8') as f:
    json.dump(config, f, indent=2, ensure_ascii=False)
python
def get_status(self, task_id: str) -> Optional[Dict]:
    status_path = self._get_status_path(task_id)

    if not status_path.exists():
        return None

    with open(status_path, 'r', encoding='utf-8') as f:
        return json.load(f)
python
def get_result(self, task_id: str) -> Optional[Dict]:
    result_path = self._get_result_path(task_id)

    if not result_path.exists():
        return None

    with open(result_path, 'r', encoding='utf-8') as f:
        return json.load(f)
python
with open(self._get_result_path(task_id), 'w', encoding='utf-8') as f:
    json.dump(asdict(result_data), f, inden
...[truncated 3497 chars]
Remediation
View remediation

Remediation Suggestions

  1. Generate opaque task identifiers internally. Do not incorporate agent_id into a filesystem path. Use a UUID as the directory name and retain the agent identifier only inside metadata.
python
def _generate_task_id(self, agent_id: str) -> str:
    return uuid.uuid4().hex
  1. Validate every externally supplied identifier. If readable identifiers are required, enforce a strict allowlist and length limit:
python
import re

_TASK_ID_PATTERN = re.compile(r"^[A-Za-z0-9_-]{1,128}$")

def _validate_task_id(task_id: str) -> str:
    if not isinstance(task_id, str) or not _TASK_ID_PATTERN.fullmatch(task_id):
        raise ValueError("Invalid task ID")
    return task_id
  1. Enforce canonical path containment. Resolve both the base and destination and reject any path outside the configured root:
python
def _get_task_path(self, task_id: str) -> Path:
    task_id = _validate_task_id(task_id)
    root = self.task_dir.resolve()
    candidate = (root / task_id).resolve()

    if candidate.parent != root:
        raise ValueError("Task path escapes the configured task directory")

    return candidate
  1. Apply validation consistently to all public methods accepting task_id, including get_status(), get_result(), update_progress(), complete(), fail(), cancel(), callback registration, worker initialization, and convenience functions.

  2. Reject absolute paths and identifiers containing path separators, . or .. path components, null bytes, or platform-specific separator variants.

  3. Create the task root with restrictive permissions and ensure task files are not writable by untrusted local users. Where concurrent or adversarial local access is possible, also defend against symbolic-link substitution and time-of-check/time-of-use races by using secure directory handles and no-follow semantics.

  4. Add tests covering Unix and Windows traversal forms, absolute paths, nested separators, symbolic links, and ...[truncated 56 chars]

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (9)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The user-facing documentation is entirely in Chinese, including headings, feature descriptions, and usage guidance, with no indication that other languages are supported or that the Chinese-only presentation is intentional for a region-specific audience. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill explicitly advertises persistent task state and result storage, but it does not warn users that task metadata, progress details, and outputs may be written to disk and retained across sessions. In an agent environment, this can expose sensitive prompts, generated code, file paths, or task artifacts to other local users, later sessions, or backup/sync systems if operators assume execution is ephemeral.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The examples show user-controlled output paths such as "/output/apis/", "/projects/bi4sight/apis/", and other filesystem destinations, but the skill provides no warning that generated artifacts may be written to arbitrary locations. In practice, an agent or user could direct outputs into sensitive directories, overwrite important files, or leak generated content into shared locations if path handling is not constrained.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This Python file contains docstrings and all visible console output in Chinese, including the title, example descriptions, and status messages. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

This code permanently removes task directories with shutil.rmtree during cleanup. Although it prints after deletion, there is no prior confirmation or clear user-facing warning in the API/docstring that calling this method will irreversibly delete stored task data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The module description and surrounding natural-language documentation are written only in Chinese, which imposes a specific language context without offering an alternative or opt-in. Under the stated policy, forcing a language without user choice can be a locale/language policy violation unless clearly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The package description is written only in Chinese, which indicates a language-specific presentation without any visible opt-in or alternate locale support in this manifest. Under the stated policy, forcing a specific language without user choice can be a natural-language policy violation unless it is clearly documented as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The display name and skill description are presented in Chinese only, and this manifest does not indicate that the skill is region-specific or that users can choose their language. That creates a locale-policy concern because the skill appears to enforce one language in user-facing metadata.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The file’s user-facing natural-language strings and docstrings are entirely in Chinese (for example the module and test descriptions), with no indication that language choice is optional. Under the policy, forcing a specific language without user opt-in can be a locale/language policy violation.

Content

No source excerpt is available for this finding.