Back to skill

Security audit

Notion to Markdown

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Notion-to-Markdown exporter; its main risks are token handling, npm dependencies, and one setup guide line that allows more Notion access than the converter needs.

Install only if you are comfortable giving a local Node script and its npm dependencies access to selected Notion content. Create a dedicated Notion integration, grant Reader access only, share only the specific pages/databases you want exported, keep NOTION_API_KEY out of version control, and consider updating/pinning dependencies before use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Note
Location
references/notion-api-setup.md:28
Finding

Setup Guide Permits Unnecessary Editor Access

Content
View full analysis

Vulnerability Details

File Location: references/notion-api-setup.md:28
Vulnerability Type: Least-privilege violation
Risk Level: Low

Vulnerable Code Snippet

markdown
5. Grant "Editor" or "Reader" access

Technical Analysis

The setup guide allows users to grant the Notion integration Editor access even though the implementation performs only read operations. The relevant application behavior consists of retrieving page metadata, reading page blocks, and querying databases:

javascript
const page = await notion.pages.retrieve({ page_id: pageId });
const mdblocks = await n2m.pageToMarkdown(pageId);
const response = await notion.databases.query({ database_id: databaseId });

No implemented or declared conversion feature requires modification of Notion content. Permitting Editor access therefore exceeds the minimum privileges necessary for the Skill's functionality.

The application loads the integration token from NOTION_API_KEY and supplies it to the Notion client. If that credential or a process with access to it is compromised, the unnecessary Editor permission could provide write capabilities over all content shared with the integration.

Attack Path

  1. A user follows the setup guide and grants the integration Editor access.
  2. The user stores the integration token in NOTION_API_KEY or a local .env file.
  3. An attacker compromises the token, the local execution environment, or a dependency running in the same process.
  4. The attacker authenticates to the Notion API using the compromised token.
  5. Because the integration has Editor rather than Reader access, the attacker may modify shared Notion content instead of being limited to reading it.

Impact Assessment

The excessive permission applies to pages and databases shared with the integration. A successful attacker could potentially alter content within that scope, subject to the capabilities enabled for the Notion integration. It does not grant access t ...[truncated 319 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the vulnerable instruction with an explicit least-privilege requirement:
markdown
5. Grant Reader access only. Editor access is not required by this converter.
  1. Remove or revise the unrelated write-permission guidance at references/notion-api-setup.md:75 so the guide does not imply that write access is needed:
markdown
### Required Permissions

This converter requires Reader access only. Do not grant write or Editor permissions.
  1. Keep the existing recommendation to share only the specific pages and databases that need to be exported.

  2. Use a dedicated Notion integration token for this converter and rotate it if compromise is suspected.

  3. Document that granting Editor access increases the impact of token or dependency compromise without enabling any additional converter functionality.

Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/convert.js a1b2c3d4e5f6g7h8 > my-page.md

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/convert.js a1b2c3d4e5f6g7h8 > my-page.md

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/convert.js a1b2c3d4e5f6g7h8 > my-page.md

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 · SKILL.md (reported line 187)May include surrounding context.

Security Note: Add .env to .gitignore to prevent accidentally committing your API key:

bash
echo ".env" >> .gitignore

Finding IDs

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 · SKILL.md (reported line 158)May include surrounding context.

md
*
 * Environment:
 *   NOTION_API_KEY - Your Notion API token (required)
 *   .env file - Create a .env file with NOTION_API_KEY=your_token
 */

require("dotenv").config();

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/convert.js (reported line 13)May include surrounding context.

js
*
 * Environment:
 *   NOTION_API_KEY - Your Notion API token (required)
 *   .env file - Create a .env file with NOTION_API_KEY=your_token
 */

require("dotenv").config();

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
89% confidence
Finding

The lockfile pins form-data to 4.0.5, which is flagged for a CRLF injection issue in multipart field names. While this package is only present as a transitive dependency here and this file alone does not prove the skill directly constructs attacker-controlled multipart field names, the dependency is real and could become exploitable if untrusted Notion-derived content or user input is ever passed into multipart requests by the dependency chain.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

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 22)May include surrounding context.

md
- `NOTION_API_KEY` - Your personal Notion integration token (required)

**Security Best Practices:**
1. **Create a dedicated integration** - Go to [notion.so/my-integrations](https://www.notion.so/my-integrations) and create an integration for this tool only
2. **Use read-only permissions** - Grant the integration "Reader" access, not "Editor"
3. **Share selectively** - Only share specific pages/databases with the integration, not your entire workspace
4. **Protect your token** - Never commit `.env` files containing `NOTION_API_KEY` to version control

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 · references/notion-api-setup.md (reported line 5)May include surrounding context.

md
## Getting Your API Key

### Step 1: Create a Notion Integration

1. Go to [Notion Integrations](https://www.notion.so/my-integrations)
2. Click "Create new integration"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency uses a caret version range, which permits automatic installation of newer compatible releases. This increases supply-chain risk because a compromised or malicious upstream release could be pulled into future installs without deliberate review or lockfile enforcement.

Content

Scanner excerpt · scripts/package.json (reported line 11)May include surrounding context.

json
"notion-to-md": "convert.js"
  },
  "dependencies": {
    "@notionhq/client": "^2.2.0",
    "dotenv": "^16.0.0",
    "notion-to-md": "^3.1.9"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dotenv package is referenced with a caret range, allowing npm to resolve to later patch and minor versions over time. In a tool that may handle Notion API tokens, this creates avoidable supply-chain exposure if an upstream release becomes malicious or introduces unexpected behavior.

Content

Scanner excerpt · scripts/package.json (reported line 12)May include surrounding context.

json
},
  "dependencies": {
    "@notionhq/client": "^2.2.0",
    "dotenv": "^16.0.0",
    "notion-to-md": "^3.1.9"
  },
  "devDependencies": {},

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The notion-to-md dependency is not pinned to an exact version, so future installs may fetch different code than originally tested. Because this skill exports potentially sensitive Notion content, a compromised dependency could affect confidentiality or integrity of exported data even if the current manifest looks harmless.

Content

Scanner excerpt · scripts/package.json (reported line 13)May include surrounding context.

json
"dependencies": {
    "@notionhq/client": "^2.2.0",
    "dotenv": "^16.0.0",
    "notion-to-md": "^3.1.9"
  },
  "devDependencies": {},
  "scripts": {