Back to skill

Security audit

Notion DB Weekly Report Generator

Security checks for vulnerabilities and agentic risk

Overview

This weekly report skill is functional, but it should go to Review because it automatically adds payment links and ships billing-contract material that is not clearly scoped to report generation.

Review this skill before installing. It appears to run locally and generate weekly report markdown, but users should be aware that normal output includes monetization metadata and a payment link, and the package contains billing-contract documentation that is broader than the report task. Only use it where the payment-link behavior is desired, and avoid rendering reports from untrusted task records in permissive Markdown viewers without sanitization.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/notion_db_weekly_report_generator.py:59
Finding
Unescaped Record Data Allows Markdown Content Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/notion_db_weekly_report_generator.py`, lines 59–75 **Vulnerability Type**: Markdown content injection **Risk Level**: Medium ```python lines = [ f"# {week_label} 周报", "", "## 数据概览", f"- 总任务数:{total}", f"- 已完成:{done}", f"- 进行中:{in_progress}", f"- 平均进度:{avg_progress}%", "", "## 本周亮点", ] lines.extend([f"- {item}" for item in (highlights or ["暂无高进度事项"])]) lines.append("") lines.append("## 风险与阻塞") lines.extend([f"- {item}" for item in (top_risks or ["暂无明显阻塞"])]) ``` ### Technical Analysis The report generator inserts the untrusted `week_label` and task titles directly into Markdown without escaping Markdown metacharacters, filtering raw HTML, or validating embedded URLs. An attacker can supply titles containing headings, links, images, HTML elements, or other Markdown syntax. Depending on the eventual Markdown renderer, this can alter the apparent structure of the report, introduce phishing content, or load an external resource. For example, a title containing an external Markdown image can cause a compatible renderer to request an attacker-controlled URL when a user opens the generated report. A malicious title is only included in the report when it qualifies as a highlight or risk. The attacker can ensure this by assigning a progress value of at least 80 or below 40. ### Attack Path 1. The attacker supplies an otherwise valid record with a title such as: ```text ![Weekly report chart](https://attacker.example/track?id=123) ``` 2. The attacker sets `progress` to `100`, causing the title to be included in the highlights section, or to `0`, causing it to be included in the risks section. 3. `validate_payload` preserves the title without Markdown escaping. 4. `_build_report` interpolates the title directly into the generated Markdown. 5. A victim opens the report in a Markdown renderer that per ...[truncated 863 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Escape Markdown metacharacters in every untrusted value before interpolation, including `week_label` and record titles. 2. If only plain text is required, reject or neutralize raw HTML, Markdown links, image syntax, and line breaks. 3. Apply explicit length limits to report fields to reduce content abuse and resource consumption. 4. Configure downstream Markdown renderers to disable raw HTML and block external images or other remote resources. 5. If links must be supported, parse them and allow only approved schemes such as `https`, with optional hostname allowlisting. 6. Add tests covering injected headings, links, images, raw HTML, multiline titles, and dangerous URL schemes. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/notion_db_weekly_report_generator.py:19
Finding
Unencoded User Identifier Allows Payment URL Query Manipulation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/notion_db_weekly_report_generator.py`, lines 19–21 **Vulnerability Type**: URL query-parameter injection **Risk Level**: Low ```python base = os.getenv("SKILLPAY_TOPUP_BASE_URL", "https://skillpay.me/pay").strip() sep = "&" if "?" in base else "?" return f"{base}{sep}user_id={user_id}" ``` ### Technical Analysis The application appends the attacker-controlled `user_id` directly to a payment URL without percent-encoding it as a query-parameter value. Validation only requires the identifier to be nonempty, so reserved URL characters such as `&`, `=`, `#`, and control characters are accepted. Consequently, an attacker can terminate the intended `user_id` value and inject additional query parameters or a URL fragment. The exact downstream effect depends on how the payment service or consuming application interprets those parameters. The configured base URL is also accepted without scheme or hostname validation. Although changing the environment requires deployment-level control, validation would provide defense in depth against configuration mistakes. ### Attack Path 1. The attacker submits a payload containing a crafted identifier, for example: ```text legitimate-user&redirect=https://attacker.example ``` 2. `validate_payload` accepts the value because it is nonempty. 3. `_payment_url` concatenates it directly into the URL. 4. The returned upgrade object contains a URL similar to: ```text https://skillpay.me/pay?user_id=legitimate-user&redirect=https://attacker.example ``` 5. A user or downstream component follows or displays the manipulated payment link. 6. If the payment service recognizes the injected parameter, it may alter payment-page behavior, redirect flow, attribution, or other request semantics. ### Impact Assessment This vulnerability does not provide local code execution, filesystem access, or additional system privileges. Its scope is limited to gen ...[truncated 459 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Construct the URL with standard URL parsing and encoding functions instead of string concatenation. 2. Encode `user_id` with `urllib.parse.urlencode` or an equivalent query-building API. 3. Preserve existing query parameters by parsing them with `urlsplit` and `parse_qsl`, adding the new value, and rebuilding the URL with `urlunsplit`. 4. Validate that the configured payment URL uses HTTPS and, where operationally possible, require an approved hostname. 5. Reject control characters and impose a reasonable length and character policy on `user_id`. 6. Add tests for identifiers containing `&`, `=`, `#`, percent signs, Unicode characters, spaces, and newline characters. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (8)

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
This file documents a billing/charge workflow for a skill whose stated purpose is only weekly report generation, creating a strong capability-purpose mismatch. Even as reference documentation, it normalizes collection of payment data and top-up flows that are unrelated to the declared function, which can enable unauthorized charging logic, hidden monetization, or expansion into financial handling without clear user consent or architectural justification.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
Including payment processing capability in a basic weekly report generator is dangerous because it introduces a sensitive financial action unrelated to the advertised task-processing role. In this context, the mismatch increases suspicion: users and reviewers would not expect charge endpoints, payment URLs, or balance handling in a report formatter, making hidden billing behavior easier to conceal and more damaging if activated.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The title and documented purpose indicate the skill is specifically a Chinese-language weekly report generator ("周报生成器"), but the file does not state that language selection is optional or limited for a justified regional/compliance reason. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The skill generates payment URLs from untrusted environment configuration and injects monetization logic into a utility whose stated purpose is weekly report generation. This is dangerous because it can redirect users to arbitrary payment endpoints or enable deceptive upsell behavior unrelated to the core function, creating phishing and trust-boundary risks.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
Multiple user-facing strings are fixed in Chinese, including default field values, report headings, and the premium-upgrade message. For a general-purpose weekly report generator, this forces a specific language without user opt-in, which matches the locale policy violation criteria.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The code always includes upgrade and payment details in normal successful output, despite the description claiming premium hooks are merely reserved. Exposing monetization metadata in routine responses increases the chance of covert solicitation, social engineering, or downstream UI components presenting unrequested payment prompts to users.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
This code hard-codes Chinese titles, owner names, statuses, and later asserts a Chinese markdown heading, which indicates the skill behavior is expected to operate in a single language. For a non-region-specific skill, forcing one locale without opt-in can violate language/locale policy requirements.

Static analysis

No suspicious patterns detected.