Back to skill

Security audit

Notion Publisher

Security checks for vulnerabilities and agentic risk

Overview

This Notion publishing skill appears legitimate, but it needs review because it uses a powerful Notion token and can replace existing page content.

Install only for Notion databases you are comfortable letting this integration read and modify. Use the least-privileged Notion integration, share only the target database, avoid passing tokens on the command line, protect ~/.notion_publish/.env with restrictive permissions or use a safer secret store, and confirm any replace/update operation before running it.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/notion_publisher.py:72
Finding

Insecure Storage and Command-Line Handling of the Notion Integration Token

Content
View full analysis
None: env_path = CONFIG_DIR / ".env" if not env_path.exists(): return for raw_line in env_path.read_text(encoding="utf-8").splitlines(): line = raw_line.strip() if not line or line.startswith("#") or "=" not in line: continue key, value = line.split("=", 1) key = key.strip() value = value.strip().strip('"').strip("'") os.environ.setdefault(key, value) ``` The token is then retrieved from either a command-line argument or the environment: ```python token = args.token or os.environ.get("NOTION_TOKEN") ``` The global command-line option permits the secret to be passed directly in process arguments: ```python parser.add_argument("--token", help="Notion integration token. Defaults to NOTION_TOKEN.") ``` ### Technical Analysis The application supports a plaintext `.env` file for storing a Notion integration token, but neither the documentation nor the ...[truncated 3371 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (38)

Tainted flow: 'req' from os.environ.get (line 115, 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/notion_publisher.py (reported line 126)May include surrounding context.

python
},
        )
        try:
            with urllib.request.urlopen(req, timeout=30) as response:
                return json.loads(response.read().decode("utf-8"))
        except urllib.error.HTTPError as exc:
            body = exc.read().decode("utf-8", errors="replace")

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The manifest describes a narrower publishing/template workflow, but the instructions also cover searching pages, updating existing content, prompting for credentials, and performing external image lookup. This mismatch can mislead users and upstream policy systems about what the skill actually does, causing overbroad invocation and unintended data access or modification in Notion.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`scripts/notion_publisher.py`

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The skill instructs the agent to obtain and use a Notion token from the environment or a local .env file, which creates a direct credential-access path. In an agent setting, reading local secret material is high risk because broad triggers or prompt confusion could cause credential use outside the user's intended scope, and the token grants read/write access to shared Notion resources.

Content

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

The CLI runtime uses the official Notion API and requires NOTION_TOKEN in the environment or in:

text
~/.notion_publish/.env

Example:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/notion_publisher.py (reported line 73)May include surrounding context.

python
def read_env_file() -> None:
    env_path = CONFIG_DIR / ".env"
    if not env_path.exists():
        return
    for raw_line in env_path.read_text(encoding="utf-8").splitlines():

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill clearly instructs use of shell commands, file reads/writes, environment-based token access, and network/API calls, but it declares no explicit tool scope or permissions boundary. That increases the chance the agent will execute higher-risk capabilities than a caller expects, especially when the trigger text is broad and the skill can touch local files and external services.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
---
name: notion-publisher
description: Publish articles to Notion using cached local copies of the target database's default Notion template when available. Use this skill when the user types /notion-publisher, asks to publish an article to Notion, create a Notion article page, draft a post into a Notion database, use an existing Notion article template, refresh the local template cache, or infer article metadata such as slug, summary, tags, category, status, cover, and template before creating a Notion page.
---

# Notion Publisher Skill

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation text is broad enough to match many generic requests about publishing, drafting, metadata inference, and template use. Overbroad triggering can cause the agent to enter a workflow that reads local config, accesses credentials, or contacts Notion and external sites in situations where the user did not intend this specific high-capability skill to run.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The Trigger section uses ambiguous natural-language requests like publish, draft, or create an article page, which can overlap with ordinary assistant tasks. In this skill, ambiguous activation is more dangerous because the workflow includes external API use, local file operations, and possible modification of existing Notion content.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
To get a Notion token:
1. Open Notion's integrations/creator dashboard.
2. Create a new internal integration in the target workspace.
3. Open the integration's Configuration tab and copy the Internal Integration Secret.
4. Enable the capabilities needed for publishing, including read content, update content, and insert content.
5. Share the target Notion database or parent page with the integration through the Content access tab or Notion's Add connection menu.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The instruction to 'Prefer neutral numbering such as 一、... and 二、...' imposes a specific language/locale convention on generated content. This is a natural-language policy concern because the skill does not ask the user for language or locale preference before enforcing that formatting style.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill directs the agent to use general web/image search and third-party image sources to find covers and inline images. That can transmit article topics, inferred metadata, and user intent to external services unrelated to Notion, expanding the data exposure surface beyond the stated core task.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The skill explicitly instructs outbound requests to third-party services such as the Art Institute API and image hosts. Even if only keywords are sent, those requests can leak sensitive article themes, unpublished editorial plans, or user interests to external domains outside the primary Notion workflow.

Content

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

md
- Search the API for public-domain artworks with `image_id`, then build:
     `https://www.artic.edu/iiif/2/{image_id}/full/843,/0/default.jpg`
   - Good search query shape:
     `https://api.artic.edu/api/v1/artworks/search?q={keywords}&query[term][is_public_domain]=true&fields=id,title,artist_display,image_id,is_public_domain`
3. Alternate artwork sources:
   - The Met Open Access: use the object API's `primaryImage` or `primaryImageSmall` JPEG URL when `isPublicDomain` is true.
   - Rijksmuseum: use IIIF URLs like `https://iiif.micr.io/{id}/full/max/0/default.png` when an image id is available.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest specifically claims publishing 'using cached local copies of the target database's default Notion template when available' and mentions refreshing the local template cache. This file contains config handling and local .env loading, but no template retrieval, caching, refresh logic, or application of a cached database template when creating pages.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.