Back to skill

Security audit

tool-save-to-notion

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent Notion-saving purpose, but it can automatically fetch user-supplied URLs and create persistent Notion records with insufficient scoping and safeguards.

Review this before installing if your agent may handle private links, internal URLs, or sensitive repositories. Use it only with a tightly scoped Notion integration token and require explicit confirmation before fetching a URL or creating a Notion page. Avoid using the curl template with untrusted page text unless JSON is generated by a safe serializer.

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

Error
Location
scripts/save-to-notion.py:43
Finding

Unrestricted User-Controlled URL Fetching Enables Server-Side Request Forgery

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:80
Finding

Documented Dynamic Curl Pattern Can Enable Shell Command Injection

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (17)

Tainted flow: 'req' from os.environ.get (line 172, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The script performs an outbound fetch to a user-supplied URL in extract_cover_image() with no allowlist or private-address validation. This creates an SSRF primitive that can be abused to probe internal services, access cloud metadata endpoints, or force the host running the skill to make arbitrary network requests.

Content

Scanner excerpt · scripts/save-to-notion.py (reported line 69)May include surrounding context.

python
url,
            headers={'User-Agent': 'Mozilla/5.0 (compatible; NotionTool/1.0)'}
        )
        with urllib.request.urlopen(req, timeout=10) as response:
            html = response.read().decode('utf-8', errors='ignore')

        # Parse meta tags

Tainted flow: 'req' from os.environ.get (line 172, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/save-to-notion.py (reported line 183)May include surrounding context.

python
method='POST'
        )

        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode('utf-8'))
            return {
                'success': True,

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill description says to use this skill whenever the user provides ANY tool URL and mentions generic save/add/bookmark phrasing. That activation scope is overly broad and can cause the agent to invoke the skill for routine bookmarking or unrelated save requests, leading to unintended web fetching and creation of persistent Notion records without sufficiently specific user intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill does not clearly warn users that it will fetch the provided URL, extract metadata/content, and send structured data to Notion where it becomes a persistent record. That lack of disclosure undermines informed consent and can expose sensitive URLs, private repo metadata, or internal tool references to an external service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill body is written to operate in Chinese and provides Chinese-only user-facing response templates such as the success and error messages. There is no indication that language is selectable or that the locale restriction is required for a region-specific purpose, which can violate language/locale policy expectations.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instruction to immediately use the skill for broad categories of links and generic trigger words removes ambiguity checks and pushes the agent toward automatic execution. In context, that means external fetching and third-party transmission may occur even when the user did not clearly request storage in Notion, increasing privacy and integrity risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

The direct reference to the Notion API endpoint indicates outbound data transfer to an external service. In the skill context this is not inherently malicious, but it increases risk because the skill also instructs automatic fetching and packaging of remote page metadata, which can leak sensitive information if users provide private or internal links.

Content

Scanner excerpt · SKILL.md (reported line 84)May include surrounding context.

使用以下 API 调用(一次性创建页面,同时设置封面和正文图片):

bash
curl -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_API_KEY" \
  -H "Notion-Version: 2021-05-13" \
  -H "Content-Type: application/json" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

The direct reference to the Notion API endpoint indicates outbound data transfer to an external service. In the skill context this is not inherently malicious, but it increases risk because the skill also instructs automatic fetching and packaging of remote page metadata, which can leak sensitive information if users provide private or internal links.

Content

Scanner excerpt · SKILL.md (reported line 84)May include surrounding context.

使用以下 API 调用(一次性创建页面,同时设置封面和正文图片):

bash
curl -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_API_KEY" \
  -H "Notion-Version: 2021-05-13" \
  -H "Content-Type: application/json" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

This duplicate endpoint reference reinforces that the workflow depends on authenticated outbound transmission to Notion. The surrounding skill design makes this more dangerous than a generic API example because activation is broad and automatic, so external transfer may happen with insufficient user awareness or confirmation.

Content

Scanner excerpt · SKILL.md (reported line 430)May include surrounding context.

API 调用模板

bash
curl -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_API_KEY" \
  -H "Notion-Version: 2021-05-13" \
  -H "Content-Type: application/json" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

This duplicate endpoint reference reinforces that the workflow depends on authenticated outbound transmission to Notion. The surrounding skill design makes this more dangerous than a generic API example because activation is broad and automatic, so external transfer may happen with insufficient user awareness or confirmation.

Content

Scanner excerpt · SKILL.md (reported line 430)May include surrounding context.

API 调用模板

bash
curl -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_API_KEY" \
  -H "Notion-Version: 2021-05-13" \
  -H "Content-Type: application/json" \

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This JSON eval file contains multiple generic activation-style phrases such as '保存这个工具', '把这个添加到我的工具箱', and '帮我保存这个链接到工具箱' that resemble ordinary conversational requests rather than narrowly scoped triggers. Because manifest/JSON files are in scope for SQP-1, these broad phrasings can indicate ambiguous invocation conditions without explicit constraints or negative examples.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The usage example and allowed type values require Chinese labels such as "网站" and "工具包", and the CLI choices later enforce that locale-specific vocabulary. This is a natural-language policy concern because the skill forces a specific language without opt-in or documented justification.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/save-to-notion.py (reported line 18)May include surrounding context.

python
NOTION_API_KEY = os.environ.get('NOTION_API_KEY', '')
DATABASE_ID = '6f7bb9cc-ac01-41c5-9856-fb1568d197ae'
NOTION_API_URL = 'https://api.notion.com/v1/pages'

# Valid types (exactly 5 options)
VALID_TYPES = {'软件', '网站', '浏览器插件', 'Prompt', '工具包'}

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

VALID_TYPES is restricted to Chinese strings only, which means users must interact in that locale even though the script otherwise uses English identifiers and help text. This is a policy violation under the language/locale rule because no alternative locale or explicit user choice is provided.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code fetches the user-supplied URL and later sends tool metadata to Notion, which transmits user-provided data and remote resource references over the network. While the module docstring states the script saves to Notion, there is no explicit warning, confirmation, or user-facing notice about external network access or data transmission when the script runs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

All prompts and expected outputs in this file are written in Chinese, which may imply the skill is evaluated or expected to operate in a fixed language. For policy compliance, language constraints should be explicitly optional or justified rather than implicitly enforced across all examples.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script reads a credential from the environment and uses it for authenticated API calls, but provides no warning in its help text or runtime output that it depends on and will use this sensitive token. For safety auditing, credential use should be disclosed so operators understand the authentication context.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.