Back to skill

Security audit

媒体广告流量市场分析

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its ad-analysis purpose, but it deserves review because it performs authenticated remote actions, defaults to a shared demo token, allows credential-bearing custom endpoints, and persists session cookies on disk.

Before installing, treat this as a real authenticated MediaInsight client, not a local-only analysis helper. Avoid using it for sensitive or proprietary analysis with the shared demo token, do not pass custom --mcp-url or --base-url values unless you fully trust the endpoint, prefer --dry-run before creating tasks, and delete generated session files when finished. Be cautious with --extract-dir because downloaded archives are extracted without strong resource limits.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/mediainsight_client.py:49
Finding

Credentials Can Be Transmitted to Arbitrary User-Selected Endpoints

Content
View full analysis
None: self.mcp_url = mcp_url.rstrip("/") self.authorization = authorization.strip() self.session_id: str | None = None def _request(self, payload: dict[str, Any]) -> dict[str, Any]: data = json.dumps(payload, ensure_ascii=False).encode("utf-8") request = Request(url=self.mcp_url, data=data, method="POST") request.add_header("Accept", "text/event-stream, application/json") request.add_header("Content-Type", "application/json") if self.authorization: request.add_header("Authorization", self.authorization) ``` ```python # scripts/mediainsight_client.py:174-188 def resolve_media_insight_auth( token: str, *, mcp_url: str = DEFAULT_MCP_URL, ...[truncated 3509 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mediainsight_client.py:315
Finding

Live Authentication Cookies Are Persisted in Plaintext and Temporary Session Files Are Retained

Content
View full analysis
None: payload = _load_session_payload(self.session_file) if not payload: return saved_base_url = str(payload.get("base_url") or "").rstrip("/") if saved_base_url: self.base_url = saved_base_url cookies = payload.get("cookies", {}) if not isinstance(cookies, dict): return for name, value in cookies.items(): self.cookie_jar.set_cookie(_make_cookie(self.base_url, str(name), str(value))) def _save_session(self) -> None: payload = { "base_url": self.base_url, "cookies": _cookies_as_dict(self.cookie_jar), } self.session_file.write_text( json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8", ) ``` ```python # scripts/mediainsight_client.py:330-333 def set_ttc_token(self, token: str) -> None: self.ttc_token = token.strip() self.cookie_jar.set_cookie(_make_cookie(self.base_url, "_mz_ttc_tkt", self.ttc_token)) self._save_session() ``` ```python # scripts/submit_ad_task.py:446-451 session_file = Path(args.session_file) if args.session_file else None if session_file is None: tmp = NamedTemporaryFile( prefix="mediainsight-skill-", suffix=".json", delete=False, ) tmp.close() session_file = Path(tmp.name) ``` ```python # scripts/download_ad_task_report.py:153-158 if args.session_file: session_file = Path(args.session_file) else: tmp = NamedTemporaryFile( prefix="mediainsight-download-", suffix=".json", delete=False, ) ...[truncated 2069 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/submit_ad_task.py:24
Finding

Reusable Demo Bearer Token Is Hardcoded in the Public Skill Package

Content
View full analysis
str: if args.token: return args.token.strip() if args.token_file: return Path(args.token_file).read_text(encoding="utf-8").strip() env_token = os.environ.get("MEDIAINSIGHT_MCP_TOKEN", "").strip() if env_token: return env_token return DEFAULT_DEMO_TOKEN ``` ### Technical Analysis The source contains a JWT-like reusable bearer token and uses it automatically as the authentication fallback. The comments and documentation acknowledge that it is public and intended to have limited permissions, so this is not a concealed credential. Nevertheless, placing a live bearer credential in a distributed package means its use cannot be restricted to the Skill, individual users, or approved execution contexts. Because the token is reusable outside the package, source publication provides every recipient with the same authority. Any later accidental expansion of its permissions would immediately increase the impact for all copies already distributed. ### Attack Path 1. An attacker downloads or reads the public Skill package. 2. The attacker copies `DEFAULT_DEMO_TOKEN` from the source. ...[truncated 797 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/download_ad_task_report.py:191
Finding

Report Archive Extraction Has No Resource or Collision Limits

Content
View full analysis
str: return re.sub(r"[\\/:*?\"<>|]+", "-", name).strip() or "report" ``` ### Technical Analysis The extraction code sanitizes path separators and therefore prevents straightforward archive path traversal through names such as `../../file`. However, it performs no validation of: - Total uncompressed archive size. - Individual entry size. - Number of entries. - Compression ratio. - Available disk space. - Expected report file types. - Duplicate output names after normalization. `archive.read(info)` loads an entire uncompressed member into memory before writing it. A highly compressed member can therefore cause memory exhaustion, while multiple large members can exhaust disk space. Different archive paths can normalize to the same filename—for example, `a/b.csv` and `a:b.csv`—allowing a later entry to overwrite an earlier extracted file. The report originates from a remote service. If that service, its delivery path, or the configured base URL is compromised, archive content must be treated as untrusted. ### Attack Path 1. The user requests a report download with `--extract-dir`. 2. A compromised service, malicious configured API endpoint, or corrupted report supplies a crafted ZI ...[truncated 939 chars]
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 (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill description understates key behaviors such as authenticating with an external platform, using a demo token, switching tenant context, creating remote jobs, and writing payload/session data to disk. In context, this is especially risky because ad-platform accounts and tenant context can expose or modify business data, so hidden side effects materially change the trust and approval model for the skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description understates key behaviors such as authenticating with an external platform, using a demo token, switching tenant context, creating remote jobs, and writing payload/session data to disk. In context, this is especially risky because ad-platform accounts and tenant context can expose or modify business data, so hidden side effects materially change the trust and approval model for the skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description is entirely written as a direct Chinese-only user interface and explicitly instructs users to describe requirements in natural language, but it does not offer any language/locale option or state that the skill is intentionally restricted to Chinese-speaking users. 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.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares capabilities that require environment access, filesystem reads/writes, MCP interaction, and network access, but it does not define any explicit tool scope or permission boundary. This increases the chance of overbroad execution in a host agent, making unintended file access, token use, or remote actions harder to constrain or audit.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation distributes a public shared demo token for accessing an external service. Shared credentials are inherently unsafe: they undermine accountability, can be abused by anyone who obtains the skill, may expose shared account data, and encourage users to run authenticated actions without understanding who else can access the same account.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill encourages use of a public shared demo token but does not clearly warn that activity may be visible to other users of the same account, that downloaded reports may contain shared or sensitive data, or that submitted tasks may be attributable only weakly. This creates avoidable privacy, data-leakage, and cross-user interference risks, especially in a market-analysis context where business intelligence may be sensitive.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest scope is ad-traffic analysis, but the default prompt expands behavior to using a shared demo token and promoting bundled annual-market PDFs. This creates a scope mismatch that can mislead users about what resources are being accessed and encourages use of credentials/assets outside the narrowly declared analytics function.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Telling the agent to '先用公开共享的 demo token 试跑' encourages use of a public/shared credential, which is unsafe even if intended for convenience. Shared tokens reduce accountability, may violate least-privilege principles, can expose usage to unauthorized parties, and may cause data access, abuse, or service-consumption under a common identity.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The default prompt is broad enough to trigger on generic requests for ad traffic distribution or trends, and implicit invocation is enabled. In combination, this increases the chance the skill activates in contexts the user did not specifically intend, potentially causing unanticipated external tool use and token-based API access.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The manifest describes a data analysis skill for querying ad traffic distribution and trends. In addition to expected report retrieval, this script reads credentials from MEDIAINSIGHT_MCP_TOKEN and creates a session file on disk, which are credential/session-handling capabilities not implied by the stated analytical purpose itself.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script downloads arbitrary report archives to local disk and optionally extracts ZIP contents without validating archive structure, file count, file sizes, or compression ratio. Although it sanitizes filenames to reduce path traversal risk, it still fully trusts server-supplied archive content, which can enable resource exhaustion or unsafe file drops if the remote endpoint is compromised or returns malicious content. This also expands the skill from data querying into filesystem write operations, increasing blast radius in an agent environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The client persists session cookies and the TTC auth token to a predictable local file (.mediainsight-session.json) without any protection, permission hardening, encryption, or explicit consent. On shared systems or multi-user agent environments, another process or user could read the file and reuse the token/cookies to impersonate the account and access tenant data.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes a data-analysis skill for querying advertising traffic distribution and trends. However, the code includes active account login and tenant-switching capabilities, which are operational account-management behaviors rather than obvious analysis-only functionality.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest frames the skill as a query/analysis tool for traffic distribution and trends. In code, it not only queries dictionaries and task results, but also submits new tasks and downloads generated report files, which goes beyond a narrow read-only analytics description.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script embeds a hard-coded bearer-style demo token and automatically falls back to it when the user does not provide credentials. Even if labeled as public/demo, packaging a live token in distributed code enables unauthorized reuse, makes abuse attribution difficult, and normalizes implicit authentication to a third-party service without explicit user consent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The file sets default industry, advertiser, and brand names in Chinese and later parses/matches Chinese demographic and regional naming conventions. This enforces a specific locale assumption in the skill behavior without explicit user opt-in or an offered locale choice, which fits the language/locale policy violation category.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill description presents this as a query/analysis capability, but the implementation calculates coin cost and can create remote tasks via task_add. This expands the trust boundary from local analysis into authenticated state-changing operations on an external platform, which can incur costs, create persistent artifacts, or trigger unintended processing under the user's account.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

A temporary JSON file is created for session state and the script later includes its path in output, but there is no explicit warning that authentication material may persist on disk. On multi-user systems or in logged command outputs, this increases the chance that others discover and exfiltrate the session artifact.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The code creates a session file on disk by default, persisting login state even when the user did not request persistence. For an analytics skill, silent credential/session storage increases the risk of token leakage through shared hosts, backups, temp-directory exposure, or later disclosure of the printed session path.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The script writes the fully resolved task payload to a user-specified path, which may contain business-relevant targeting and campaign information. There is no confirmation prompt or visible warning at the write site that this data will be persisted to disk, so users may not realize the sensitivity of the exported content.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/mediainsight_client.py:51