Back to skill

Security audit

design-inspiration-collector

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed design-inspiration collector that searches or constructs Dribbble/Pinterest links and writes local report files, with some review notes but no artifact-backed malicious behavior.

Install only if you are comfortable sending design search topics to Tavily and having Markdown/JSON reports written under ~/design_inspirations when the script is used. Treat generated links as search results, not guaranteed-safe official links, until the URL validation is hardened and the Tavily dependency is pinned.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/design_collector.py:23
Finding

Hostname Substring Matching Allows URL Allowlist Bypass

Content
View full analysis
bool: if "dribbble.com" not in url: return False allowed_patterns = [ r"dribbble\.com/search/", r"dribbble\.com/tags/", r"dribbble\.com/shots/popular", ] for p in allowed_patterns: if re.search(p, url): return True return False def is_valid_pinterest_url(url: str) -> bool: if "pinterest.com" not in url: return False allowed_patterns = [ r"pinterest\.com/search/pins", r"pinterest\.com/search/\?", r"pinterest\.com/ideas/", ] for p in allowed_patterns: if re.search(p, url): return True return False ``` ### Technical Analysis The URL validators search for trusted-domain strings and path fragments anywhere in the complete URL. They do not parse the URL or verify that the actual hostname is an approved Dribbble or Pinterest hostname. Consequently, an attacker-controlled URL can satisfy the checks merely by embedding a trusted-looking string in its hostname or path. Examples include: ```text https://dribbble.com.attacker.example/search/healthcare https://attacker.example/dribbble.com/search/healthcare https://pinterest.com.attacker.example/search/pins?q=design ``` These URLs are controlled by `attacker.example`, but the substring and regular-expression checks can accept them. Dribbble URLs received from Tavily are passed through this validation before being written to the generated Markdown and JSON reports. ### Attack Path 1. An attacker creates a page whose URL contains an allowed domain and path string but whose actual hostname is attacker-controlled. 2. The attacker causes the page to appear in search-engine results for one of the queries used by the Skill. 3. Tavily returns the m ...[truncated 814 chars]
Remediation
View remediation
bool: try: parsed = urlparse(url) host = (parsed.hostname or "").lower().rstrip(".") if parsed.scheme != "https": return False if host not in {"dribbble.com", "www.dribbble.com"}: return False return ( parsed.path.startswith("/search/") or parsed.path.startswith("/tags/") or parsed.path == "/shots/popular" or parsed.path.startswith("/shots/popular/") ) except ValueError: return False def is_valid_pinterest_url(url: str) -> bool: try: parsed = urlparse(url) host = (parsed.hostname or "").lower().rstrip(".") if parsed.scheme != "https": return False if host not in {"pinterest.com", "www.pinterest.com"}: return False return ( parsed.path == "/search/pins/" or parsed.path.startswith("/ideas/") ) except ValueError: return False ``` Add negative tests for deceptive hostnames, user-information syntax, mixed-case hosts, trailing-dot hosts, alternate ports, and trusted-domain strings embedded in paths. ]]>

T08 · Insecure Dependencies

Note
Location
skill.yaml:34
Finding

Unpinned Tavily Dependency Creates Supply-Chain Exposure

Content
View full analysis
Remediation
View remediation
``` For stronger reproducibility, reference a locked requirements file containing exact versions and SHA-256 hashes for all resolved packages. ]]>
Vulnerability Patterns
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The documented behavior and the described implementation diverge in multiple ways, including undeclared filesystem effects and output artifacts not disclosed to the user. Behavior mismatches are dangerous because reviewers and users may approve the skill for one purpose while it performs additional actions, reducing transparency and creating room for data leakage or unexpected persistence.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill description is explicitly presented as a Chinese-only capability (“双平台设计灵感收集技能”), and the document does not offer any user opt-in or alternative language behavior. Under the stated policy, forcing a specific language without user choice is a natural-language locale policy issue.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger list includes generic phrases like '找灵感', '设计参考', and platform names that can appear in ordinary design discussions, increasing the chance the skill activates without a clear user request to use this specific capability. In an agent environment, over-broad activation can cause unintended external searches, file generation, and disclosure of user topics to third-party services such as Tavily, Dribbble, and Pinterest.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill appears to require environment access, network access, and file writing, but it does not declare an explicit tool scope or permission boundary. That creates an authorization and review gap: the agent may use sensitive capabilities without clear limitation, making unintended data access or side effects harder to detect and govern.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

L003 将“找灵感、收集灵感、设计参考、UI参考、视觉灵感、设计趋势”等作为触发词,其中多项是常见中文日常/工作表达,且未限定必须是针对 Dribbble/Pinterest 收集任务时才触发。虽然描述给出了一些示例主题,但没有提供排除条件或负例来界定何时不应激活该技能。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

L003 的整体描述以中文明确规定技能行为与输出格式,但未说明是否支持其他语言,也未给用户提供语言选择或按用户语言响应的选项。根据规则,未经用户选择而隐含固定语言/locale 属于自然语言政策风险。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill instructs the agent to write a Markdown file into the workspace without requiring explicit user confirmation, path disclosure, or overwrite safeguards. Unprompted file creation can overwrite existing work, create persistence the user did not expect, or be abused when the skill is triggered accidentally.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

SQP-3 applies to all file types and covers language or locale policy violations in natural-language content. The module description and later CLI/output strings are Chinese-only, with no opt-in, alternative language, or stated region-specific justification, which can impose an unintended language constraint on users.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest says the skill should use Tavily to search official results from both Dribbble and Pinterest, then organize the returned content. In code, Dribbble uses Tavily, but Pinterest bypasses Tavily entirely and returns a fixed list of constructed search URLs, so the actual behavior does not match the claimed dual-platform search workflow.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger list contains generic terms like 'Dribbble', 'Pinterest', '设计参考', and '设计趋势' that can appear in ordinary conversation, increasing the chance the skill activates when the user did not explicitly ask for it. Unintended activation can cause inappropriate tool use, unexpected external searches, and context hijacking by routing broad design discussions into this skill.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The top-level docstring says the tool 'collects' inspiration only from official search/tag pages and excludes other content, which implies gathered results reflect actual collected sources. However, when Tavily results are insufficient, the code fabricates fallback entries in build_dribbble_urls/search_dribbble rather than collecting them from search output, creating a mismatch between the documentation's stated process and the implemented behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The natural-language description appears to assume Chinese as the interaction language without offering an alternative or documenting that the skill is intentionally language-specific. This can violate language/locale policy when no user choice or explicit scope is provided.

Content

No source excerpt is available for this finding.