Back to skill

Security audit

Liquipedia Overwatch

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly a disclosed Overwatch data scraper/cache helper, but it has unsafe local-write and command-execution patterns that users should review before installing.

Install only if you are comfortable with a skill that runs local Python/Node commands, scrapes external sites, and writes persistent cache files. Review or fix the cache path handling, avoid passing untrusted values through shell command strings, do not use personal Chrome profiles/cookies for scraping, and pin or avoid the extra multi-search-engine install.

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
SKILL.md:56
Finding

Shell Command Injection Through Interpolated URLs and JSON Data

Content
View full analysis
→ Is data present and still valid? Read structured JSON → convert to human-readable output → return directly Step 2 — Scrape Liquipedia with Playwright Scraper exec: node /userspace/skills/playwright-scraper-skill-1-2-0/scripts/playwright-stealth.js "" → Wait for page loading, then extract data from the output Step 3 — Save data in the schema.md format exec: python3 references/cache_manager.py save '' ``` The same unsafe URL invocation pattern is repeated in the command examples at lines 582-583, 616, 669, and 711. ### Technical Analysis The Skill instructs the agent to insert URLs, identifiers, and scraped JSON directly into shell command strings. Wrapping a URL in double quotes does not prevent shell command substitution. Shell constructs such as `$(command)` and backticks are still evaluated inside double-quoted strings. Similarly, wrapping JSON in single quotes is unsafe when the JSON contains an apostrophe: the apostrophe terminates the quoted argument and allows subsequent text to be interpreted as shell syntax. The affected values can originate from user-supplied player or team names and from remotely scraped page content. The instructions do not require URL validation, shell escaping, argument-array execution, or use of standard input for JSON. ### Attack Path 1. An attacker submits a team, player, or URL-like query containing shell metacharacters, such as a command substitution expression. 2. The agent constructs a Liquipedia or OWTV URL using the supplied value. 3. Following the Skill instructions, the agent inserts the constructed URL into: ```bash node scripts/playwright-stealth.js "" ``` 4. A shell ...[truncated 952 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/cache_manager.py:67
Finding

Arbitrary JSON File Write Through Path Traversal in Cache Identifiers

Content
View full analysis
str: # player/team ID → lower-hyphen.json safe = i.lower().replace(" ", "-") if t in ("tournament", "earnings"): return f"{safe}.json" if t == "hero_picks": return f"{safe}.json" return f"{safe}.json" ``` ```python def cmd_save(data_type: str, item_id: str, json_data: str | None = None): """保存数据到缓存""" if data_type not in TYPE_DIRS: print(f"错误:未知类型 {data_type},可选: {list(TYPE_DIRS.keys())}") return if json_data is None: print("错误:请提供 JSON 数据(从 stdin 或 --data 参数)") return # 支持从 stdin 读取完整 JSON if json_data == "-": raw = sys.stdin.read() else: raw = json_data data = json.loads(raw) data["schema_version"] = data.get("schema_version", "1.0") data["cached_at"] = datetime.now(timezone.utc).isoformat() dir_ = type_to_dir(data_type) filename = id_to_filename(data_type, item_id) filepath = dir_ / filename old_data = {} if filepath.exists(): old_data = json.loads(filepath.read_text()) filepath.write_text(json.dumps(data, ensure_ascii=False, indent=2)) ``` ### Technical Analysis The function names its transformed value `safe`, but it only lowercases the identifier and replaces spaces with hyphens. It does not reject: - `../` traversal segments. - Forward or backward path separators. - Absolute paths. - Repeated dots. - Platform-specific path prefixes. The resulting filename is joined to the intended cache directory without resolving the path and verifying containment. Consequently, identifiers such as `../../target` can escape the selected cache directory. An absolute identifier can also cause `pathlib` path composition to discard the cache prefix. The later ind ...[truncated 1648 chars]
Remediation
View remediation
str: normalized = item_id.lower().replace(" ", "-") if not ID_PATTERN.fullmatch(normalized): raise ValueError("Invalid cache item ID") return normalized + ".json" ``` 2. Explicitly reject absolute paths, path separators, `.` components, and `..` components. 3. Resolve and verify the destination before any read or write: ```python base = type_to_dir(data_type).resolve() filepath = (base / filename).resolve() if filepath.parent != base: raise ValueError("Cache path escapes the expected directory") ``` 4. Apply equivalent containment checks when loading paths from `index.json`; treat the index as untrusted data. 5. Write through a temporary file inside the verified directory and atomically replace the destination only after successful validation. 6. Use restrictive file permissions where the platform permits it. 7. Add regression tests covering `../`, absolute paths, nested separators, encoded separators, long identifiers, and platform-specific path syntax. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:1343
Finding

Unpinned Third-Party Skill Installation Creates a Supply-Chain Risk

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill goes beyond querying source websites by defining a local analytics pipeline, report generation, and custom MPS scoring over disk-resident JSON files. This materially changes the trust model because the agent is instructed to process local artifacts and execute analysis tooling that is not disclosed in the high-level purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill goes beyond querying source websites by defining a local analytics pipeline, report generation, and custom MPS scoring over disk-resident JSON files. This materially changes the trust model because the agent is instructed to process local artifacts and execute analysis tooling that is not disclosed in the high-level purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation includes scripted probing of sequential OWTV match IDs using curl and HTTP status checks, which is effectively scan-like enumeration of external resources. Even if intended for data discovery, this expands the skill from normal retrieval into automated probing behavior that can violate acceptable-use expectations, trigger defenses, or be repurposed for broader enumeration patterns.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill clearly instructs reading and writing under /workspace/liquipedia-cache and invoking local scripts, but it declares no explicit tool scope or permissions boundary. That creates a capability mismatch: the runtime may permit filesystem actions that are not transparently documented or constrained, increasing the risk of unauthorized persistence or broader host interaction if the skill is triggered unexpectedly.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill mandates persistent cache writes and later generation of analysis artifacts despite presenting itself as a query tool. Hidden persistence is risky because it leaves durable local state that can affect future runs, leak prior query history, or be abused for data staging.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill requires persistent local writes without warning users that invoking the skill modifies host files. Undisclosed writes are dangerous because they create silent state changes, can retain sensitive query-derived data, and may influence future agent behavior through cache poisoning or stale artifacts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The instructions direct execution of shell commands and local scripts but do not clearly warn that using the skill may execute subprocesses on the host. This matters because command execution expands the attack surface: malformed parameters, unexpected environment interactions, or compromised helper scripts could produce unintended side effects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill describes outbound scraping of third-party sites without explicit warning that user requests may trigger network access and transmit derived query terms to external services. This can expose user interests, create compliance issues, and unexpectedly contact untrusted sites under an innocuous query-skill label.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Although branded as a Liquipedia query skill, it instructs collection from OWTV.gg and fallback use of search engines and other external sources. Broadening data acquisition paths increases outbound network exposure and raises the chance of retrieving untrusted or irrelevant content under a narrow, trusted-looking label.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill's stated purpose is querying Liquipedia Overwatch data, but these instructions add a general web-search capability via DuckDuckGo to discover tournament identifiers. General search-engine use is not an obvious requirement for a Liquipedia query skill and broadens the skill into open-ended web discovery.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

These sections define a custom MPS ranking workflow and analytical scoring model over scraped data. That is a separate analytics capability, not merely retrieval of Liquipedia Overwatch data as described in the manifest.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest says this skill activates when users ask for Liquipedia Overwatch data, which implies a data lookup/query role. However, this file exposes commands to save cached records, rewrite an index, and create directories/files under /workspace/liquipedia-cache, so the implemented behavior includes local state mutation and cache management rather than only answering data queries.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The save command accepts arbitrary JSON and writes it persistently to disk under a cache path, allowing the skill to modify local state beyond its stated purpose of answering Liquipedia Overwatch queries. In an agent setting, this broad write primitive can be abused to poison cached data, mislead later responses, or create unbounded persistent artifacts without strong validation of type, schema, provenance, or authorization.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This is a code file, so SQP-3 applies to natural-language content in docstrings and user-facing strings. The file presents its title, explanatory documentation, CLI usage, and runtime output in Chinese only, which effectively forces a specific language/locale without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The entire schema and operational guidance are written as Chinese-only instructions, including field descriptions and workflow requirements, with no indication that users may choose another language or locale. This can violate language/locale policy when a skill imposes a specific language without user opt-in or a documented region-specific justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest description is in Chinese and states activation for users asking about Liquipedia Overwatch data, while the rest of the skill instructions are also Chinese-centric. This effectively forces a specific language/locale experience without explicit user opt-in or a documented reason that the skill is limited to Chinese-language operation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The natural-language documentation and command descriptions are presented only in Chinese, which imposes a specific language on users without any opt-in or alternative. The policy requires avoiding forced language or locale constraints unless they are explicitly justified or optional.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code performs persistent file writes for cached JSON data and updates an index file, which can affect user data on disk. Although the script prints success messages after writing, there is no prior warning in the user-facing docstring or comments that using save and update-index will modify files under /workspace/liquipedia-cache/.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

文件标题及全文均以中文编写,未见任何说明该技能仅面向中文用户,或提供其他语言/本地化选择。根据规则,强制特定语言而无用户选择可能构成自然语言层面的语言/locale 策略问题。

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.