Back to skill

Security audit

alist

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent Alist admin client, but it handles powerful credentials and destructive admin actions with weak safeguards.

Install only if you trust this skill with Alist administrator-level access. Prefer HTTPS endpoints, avoid putting passwords or API keys in shell commands, clear or protect the token cache, use least-privilege Alist accounts, and manually review any delete, restore, clear, upload, download, SSH, SSO, or 2FA operation before allowing an agent to run it.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/alist_client.py:21
Finding

Administrative credentials may be transmitted over unencrypted HTTP

Content
View full analysis
dict: url = f"{self.base_url}{path}" headers = {"Content-Type": "application/json"} if self.api_key: headers["Authorization"] = self.api_key else: token = self._get_token() if token: headers["Authorization"] = token body = None if data is not None: body = json.dumps(data).encode("utf-8") if params: qs = urllib.parse.urlencode(params) url = f"{url}?{qs}" last_error = None for attempt in range(self.retries + 1): try: req = urllib.request.Request(url, data=body, headers=headers, method=method) with urllib.request.urlopen(req, timeout=self.timeout) as resp: raw = resp.read().decode("utf-8") ``` The documented examples also use plaintext HTTP: ```bash python scripts/alist_client.py --base-url http://localhost:80 --username admin --password xxx ping python scripts/alist_client.py --base-url http://localhost:80 --api-key "your-key" list /mnt/sda2 ``` ### Technical Analysis The client accepts arbitrary `base_url` values and defaults to an `http://` URL. It does not reject or warn about plaintext HTTP before placing an API key or bearer token in the `Authorization` header. The login flow similarly transmits a password-derived authentication value to the configured endpoint. Plaintext use on loopback may be acceptable in a narrowly controlled deployment, but the same unrestricted configuration supports non-loopback HTTP destinations. On an untrusted network, an observer, ma ...[truncated 1403 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/alist_client.py:22
Finding

Privileged bearer token is cached in a plaintext file without restrictive permissions

Content
View full analysis
dict: try: with open(TOKEN_CACHE_FILE, "r") as f: return json.load(f) except Exception: return {} def _save_token_cache(self): try: with open(TOKEN_CACHE_FILE, "w") as f: json.dump({ "base_url": self.base_url, "username": self.username, "token": self._token, "expiry": self._token_expiry, }, f) except Exception: pass ``` ### Technical Analysis The client writes a reusable bearer token, its associated username, base URL, and expiration time into a plaintext JSON file inside the Skill's installation directory. The file is created with the process's default permissions, which depend on the current umask. No explicit `0600` mode, ownership verification, symlink protection, atomic protected creation, or OS credential store is used. The token is treated as valid for approximately 48 hours. Any process or user able to read the Skill directory may therefore recover a live authentication credential. Storing runtime secrets alongside distributed source code also increases the risk of accidental inclusion in archives, backups, repository commits, indexing systems, or support bundles. Automatic token caching supports usability, but plaintext storage in a shared project location is broader than the ...[truncated 1114 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/alist_client.py:176
Finding

The login command discloses the bearer token through standard output or output files

Content
View full analysis
dict: self._token = None token = self._get_token() if token: return { "code": 200, "token": token, } ``` The relevant CLI dispatch and generic output handling are: ```python if action == "login": result = client.login() ``` ```python output = json.dumps(result, ensure_ascii=False, indent=2) if args.output: with open(args.output, "w", encoding="utf-8") as f: f.write(output) else: print(output) ``` The source contains an additional localized success-message field in the returned object; it does not alter the credential exposure shown above. ### Technical Analysis A successful login returns the complete bearer token as part of the normal result object. The generic CLI renderer then serializes that object and either prints it to standard output or writes it to a user-selected path. Standard output is frequently captured by terminal scrollback, AI-agent transcripts, CI/CD logs, shell command substitution, monitoring systems, and support tooling. Files created through `--output` also use default filesystem permissions rather than protected secret-file permissions. This produces a second credential-disclosure channel in addition to the token cache. A login command only needs to report success or failure. Returning the credential itself is not required for the declared automatic token-management behavior. ### Attack Path 1. A user or automation process runs the `login` action. 2. The client obtains a bearer token and includes it in the result object. 3. The generic output handler prints the token or stores it in the reques ...[truncated 681 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:16
Finding

Documentation encourages supplying passwords and API keys through command-line arguments

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:264
Finding

Skill documentation recommends downgrading TMDB traffic to plaintext HTTP

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (15)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/alist_client.py --base-url http://localhost:80 --username admin --password xxx ping

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/alist_client.py --base-url http://localhost:80 --username admin --password xxx ping

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The client defaults to an HTTP base URL and supports transmitting usernames, passwords, API keys, and bearer tokens over that channel without warning or enforcement. In realistic deployments, this exposes credentials to interception or modification by any attacker on the network path, leading to account compromise and full administrative control of the alist instance.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README advertises extensive destructive and administrative capabilities, including delete, backup/restore, user management, settings management, SSH/SFTP, audit logs, 2FA, and SSO, but provides no warning about privileged scope, destructive actions, or safe-use expectations. In an agent skill context, this increases the chance that users or downstream automation invoke high-impact operations without understanding the risk, especially when connected to production file stores or admin endpoints.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill exposes broad capabilities including environment-variable use, filesystem operations, and network access, but does not declare any explicit tool scope or permissions boundaries. In an agent setting, this increases the chance of over-privileged execution, accidental destructive actions, or credential exposure because operators and enforcement layers cannot easily constrain what the skill is allowed to do.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This skill is a full administrative client for alist and prominently documents destructive operations such as delete, move, storage disable/delete, user delete, backup restore, and task clearing without a clear warning about data loss, privilege impact, or system-wide effects. In practice, this can lead users or agents to execute irreversible actions against production storage and admin endpoints without realizing the blast radius.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
80% confidence
Finding

The documented example includes verify=False, which disables post-operation verification for a move operation. Even though the text says this is not recommended, documenting an unsafe bypass in a copy-paste-ready example can cause silent failures, misreported success, data inconsistency, or loss when moving files across storage backends.

Content

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

md
# 跨存储大文件:增加 timeout(默认查 alist 任务列表验证,避免预占空间误判)
client.move("/mnt/sda2", "/mnt/sdb1/movie", ["movie.mp4"], timeout=3600)
# 跳过验证(不推荐)
client.move("/mnt/sda2", "/mnt/sdb1/", ["x.mp4"], verify=False)
client.remove("/mnt/sda2", ["old_file.mp4"])

# 存储管理

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The examples show deletion and task-clearing operations in a normal usage flow without strong visual caution or explicit irreversibility notice. Example code is often copied verbatim, so presenting destructive commands casually increases the likelihood of accidental deletion of files, users, tasks, or configuration state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The remove method performs file or directory deletion through the API, but the implementation provides no confirmation prompt, log message, or explicit warning about the destructive effect. The CLI also exposes this action directly, increasing the chance of accidental irreversible deletion without disclosure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

L0425-L0426 的注释明确表示该方法会通过 task_download_list 验证下载完成并自动清理任务;但实际代码在 L0454-L0464 是直接从 /d/{path} 拉取内容并写入本地文件,随后在 L0491-L0492 调用 task_download_list 进行“验证”。这种注释与实现存在主动矛盾,因为该本地直连下载并不对应前文所描述的 alist 后台下载任务语义。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The download_file method creates local directories and writes downloaded content to a local path, but there is no print/log statement, confirmation, or warning disclosing that local filesystem changes will occur. For a code-file audit, this is a safety-relevant file write lacking user disclosure.

Content

No source excerpt is available for this finding.

Cloud Storage Exfiltration

Medium
Category
Data Exfiltration
Confidence
55% confidence
Finding

Data is uploaded to cloud storage (S3 / GCS / Azure Blob). This may be a legitimate backup or exfiltration to an external bucket. Manual review is recommended.

Content

Scanner excerpt · scripts/alist_client.py (reported line 1196)May include surrounding context.

python
elif action == "add-aria2":
        result = client.add_aria2(args.urls, args.save_path)
    elif action == "upload":
        result = client.upload_file(args.local_file, args.remote_dir)
    elif action == "download":
        result = client.download_file(args.remote_path, args.local_dir)
    elif action == "storage-list":

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The natural-language description and setup guidance are presented in Chinese only, which may impose a language choice on users without offering an alternative or opt-in. Under the policy, forcing a specific language without user choice can be a locale/language policy issue.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

L0946-L0949 的注释写明“测试 TMDB 连通性(通过 alist 后端)”,但实现只是调用 ping(),而 ping() 在 L0867-L0870 仅请求 /api/public/settings。读取公共设置只能证明 alist 服务可达,不能证明 TMDB API、代理配置或刮削依赖的外部连通性正常,因此注释与行为不符。

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

When --output is provided, the script writes JSON to the specified path with no confirmation, overwrite check, or prior warning. Although this is routine behavior, it is still a local file write without any protective disclosure in the code path itself.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.