Back to skill

Security audit

Qq Zone Photo

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims for QQ Zone photo management, but it handles account cookies and downloads in ways that deserve careful review before installation.

Install only if you are comfortable giving the skill QQ Zone session access and letting it read/write local photo files. Use a dedicated cookies file with restrictive permissions, avoid running it on shared systems, do not pass untrusted download URLs, review album visibility after creation, and remove the cookie file when finished.

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/qzone_photos.py:496
Finding

Unrestricted Authenticated URL Retrieval Enables SSRF and Resource Exhaustion

Content
View full analysis
str: """Download a single photo to the output directory.""" os.makedirs(output_dir, exist_ok=True) if not filename: filename = photo_url.split("/")[-1].split("?")[0] if not filename: filename = f"photo_{int(time.time() * 1000)}.jpg" filepath = os.path.join(output_dir, filename) resp = session.get(photo_url, stream=True) ``` The vulnerable function is called directly with the user-supplied `--url` argument: ```python elif args.action == "download": if not args.url: print("Error: --url is required for download action") sys.exit(1) path = download_photo(session, args.url, args.output) ``` ### Technical Analysis The `download` action accepts an arbitrary URL and requests it through an authenticated `requests.Session`. The implementation does not validate: - The URL scheme. - The destination hostname. - Whether the resolved address is loopback, private, link-local, or otherwise reserved. - Redirect destinations. - Whether the destination is an approved QQ photo or CDN endpoint. - Response size or content type. - Connection and read timeouts. Consequently, an attacker who can influence an Agent invocation can cause the process to issue HTTP requests to internal or local services. Because the same session contains cookies scoped to `.qq.com`, requests to eligible QQ subdomains may also carry the user's QQ authentication cookies. Arbitrary external hosts normally will not receive domain-scoped QQ cookies, but unrestricted redirects and broad destination support still create an unnecessary credential exposure surface. The lack of a respo ...[truncated 1541 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/qzone_photos.py:569
Finding

Path Traversal Through Remote Album Photo Names

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/qzone_photos.py:77
Finding

QQ Session Credentials Are Stored and Printed Insecurely

Content
View full analysis
None: """Save cookies to a JSON file.""" os.makedirs(os.path.dirname(path) if os.path.dirname(path) else ".", exist_ok=True) with open(path, "w", encoding="utf-8") as f: json.dump(cookies, f, indent=2, ensure_ascii=False) print(f"Cookies saved to {path}") ``` After successful login, the same sensitive values are printed to standard output: ```python if args.action == "login": result = qr_login(args.cookies) if result: print(json.dumps(result, indent=2, ensure_ascii=False)) else: print("Login failed.") sys.exit(1) ``` The printed and stored result contains: ```python result = { "qq_number": qq_number, "p_skey": all_cookies.get("p_skey", ""), "skey": all_cookies.get("skey", ""), "uin": uin, } ``` ### Technical Analysis The cookie file contains active QQ session credentials, including `p_skey` and `skey`. It is created using the process's current umask rather than a guaranteed owner-only mode. In environments with a permissive umask, the resulting file may be readable by other local users or processes. Printing the complete credential dictionary to stdout creates an additional disclosure channel. Agent frameworks, shell wrappers, CI systems, terminal recorders, or centralized logging services may capture command output and retain the credentials beyond their intended lifetime. This behavior also conflicts with the documentation's assurance that credentials are only stored locally: stdout can be collected and transmitted by the surrounding Agent or logging infrastructure. ### Attack Path 1. The user perfor ...[truncated 1032 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/qzone_photos.py:130
Finding

Predictable Shared Temporary File Permits Symlink Overwrite

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/qzone_photos.py:405
Finding

New Albums Are Silently Created as Public

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (16)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill documents and enables shell execution, local file read/write, and network access, but it does not declare any tool scope restrictions such as permissions or allowed-tools. This creates a mismatch between the skill's effective capabilities and its declared security boundary, increasing the chance an agent executes high-risk actions without explicit policy review or user awareness.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file consistently presents the skill name, description, workflow examples, invocation guide, configuration, and safety notes only in Chinese. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and 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
92% confidence
Finding

The script persists active authentication cookies to a JSON file on disk without any permission hardening, encryption, or explicit warning to the user. Anyone with local access to that file may be able to reuse the session to access the user's QQ Zone account until the cookies expire or are revoked.

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/qzone_photos.py (reported line 238)May include surrounding context.

python
try:
        system = platform.system()
        if system == "Darwin":
            subprocess.Popen(["open", image_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            print("(QR code image opened in Preview)")
        elif system == "Linux":
            subprocess.Popen(["xdg-open", image_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

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/qzone_photos.py (reported line 241)May include surrounding context.

python
subprocess.Popen(["open", image_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            print("(QR code image opened in Preview)")
        elif system == "Linux":
            subprocess.Popen(["xdg-open", image_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            print("(QR code image opened in default viewer)")
        elif system == "Windows":
            os.startfile(image_path)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This function transmits a local photo along with account session values such as p_skey and skey to remote QQ Zone endpoints. Although upload is part of the action's purpose, the code lacks any user-facing disclosure about the network transmission of local content and authentication data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The --action download path accepts an arbitrary --url and passes it directly to requests, then writes the response to disk. This turns the skill into a general authenticated fetcher/downloader rather than limiting it to QQ Zone photo URLs, enabling misuse for unexpected network access, downloading untrusted content, or hitting internal resources if run in a privileged environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The entire skill description and usage guidance are written only in Chinese, with no indication that other languages are supported or that the language requirement is optional. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency is specified with a lower bound only, which allows future unresolved versions to be installed and makes builds non-reproducible. In a skill that handles QR-code login and photo/account data, dependency drift can introduce vulnerable or incompatible releases without review.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.31.0
Pillow>=10.0.0
qrcode>=7.4.2
pycryptodome>=3.19.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding

requests has multiple known advisories, and because the manifest does not pin an exact version, it is impossible to verify whether deployment will avoid affected releases. Since this skill likely performs authenticated network access to QQ services, a vulnerable HTTP client could expose credentials, tokens, or request integrity.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

Pillow is unpinned and may resolve to different versions across installations, including versions with security defects or behavior changes. Because this skill processes user photos, image-parsing libraries are part of the attack surface and should be tightly controlled.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
requests>=2.31.0
Pillow>=10.0.0
qrcode>=7.4.2
pycryptodome>=3.19.0

Unverifiable Dependency: Pillow has 16 known advisory(ies) (CVE-2016-2533 (Pillow buffer overflow in ImagingPcdDecode); CVE-2023-50447 (Arbitrary Code Execution in Pillow); CVE-2021-27922 (Pillow Uncontrolled Resource Consumption) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding

Pillow has a history of memory-safety and resource-consumption issues, and the absence of an exact pinned version means the deployed package may still be affected. Because this skill browses, uploads, and downloads photos, malicious image files could directly reach this parsing surface.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The qrcode package is not pinned, creating supply-chain and reproducibility risk from unexpected future releases. While lower risk than network or image-parsing libraries, it still allows unreviewed code changes into the environment.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
requests>=2.31.0
Pillow>=10.0.0
qrcode>=7.4.2
pycryptodome>=3.19.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

pycryptodome is a cryptographic dependency and leaving it unpinned permits uncontrolled upgrades or resolver choices that may include vulnerable releases. In a skill using login-related flows, cryptographic correctness and version certainty are especially important.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
requests>=2.31.0
Pillow>=10.0.0
qrcode>=7.4.2
pycryptodome>=3.19.0

Unverifiable Dependency: pycryptodome has 4 known advisory(ies) (CVE-2018-15560 (PyCryptodome integer overflow vulnerability); CVE-2023-52323 (PyCryptodome and pycryptodomex side-channel leakage for OAEP decryption); CVE-2018-15560 (PyCryptodome before 3.6.6 has an integer overflow in the data_len variable in AE) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
89% confidence
Finding

pycryptodome has known advisories, and without exact version pinning there is no assurance that installations will avoid affected releases. In a skill supporting QR-code login and account-related operations, cryptographic weaknesses can undermine confidentiality or authentication guarantees.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The QR code image used for authentication is saved to a predictable temporary path on disk. While the script later prints the path, there is no prior disclosure that a login-related artifact will be created locally, which may matter on shared systems.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.