Back to skill

Security audit

Notion 2025 API Skill

Security checks across malware telemetry and agentic risk

Overview

This is a disclosed Notion API helper that uses your Notion key to read and edit shared Notion content, with some safe-use caveats.

Install only if you want OpenClaw to access and modify the Notion pages or databases you share with the integration. Use a dedicated least-privilege Notion integration, share only specific test or intended workspaces, chmod the token file to 600, review batch updates before running them, and do not pass untrusted text or property names directly into the shell helper.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (23)

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The document makes strong claims that all user input is validated and safely escaped, but later explicitly warns that passing direct user input to the script is unsafe. This inconsistency can cause operators or downstream agents to overtrust the skill's safety properties and use it in risky ways, leading to malformed requests, injection into generated JSON, or accidental misuse of privileged API credentials.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The checklist and patch notes overstate the implemented protections by claiming validation on all user-provided data, while other sections admit some direct user input patterns remain unsafe. Security documentation that overclaims coverage is dangerous because users may rely on it to process untrusted content, expanding the blast radius of any remaining injection or request-manipulation flaws in the actual skill.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The README includes copy-pastable examples that create pages and update Notion content, but it does not clearly warn users that these commands will make live changes in their remote Notion workspace. In an agent-skill context, this increases the risk of unintended state-changing actions because users or downstream tools may treat examples as safe to run without realizing they are destructive or persistent.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The examples instruct users to read a live Notion API key from a local secrets file and immediately send authenticated requests to Notion, but they do not clearly warn that credentials and workspace metadata/content will be transmitted to an external service. In a documentation context this is expected behavior for an API integration, but the lack of explicit disclosure increases the chance of accidental data exposure during copy/paste use.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Several examples create pages, update properties, append blocks, and batch-modify entries in a real Notion workspace without an explicit warning that they will change remote data. This can lead users to unintentionally alter production content, especially in the batch update example where multiple records are modified in a loop.

External Transmission

Medium
Category
Data Exfiltration
Content
NOTION_KEY=$(cat ~/.openclaw/workspace/secrets/notion_api_key.txt)
DATA_SOURCE_ID="YOUR_DATA_SOURCE_ID"  # Replace with your actual data source ID

curl -s -X POST "https://api.notion.com/v1/data_sources/$DATA_SOURCE_ID/query" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
88% confidence
Finding
This example performs an authenticated outbound request to Notion using a bearer token loaded from a local secrets file. While this is normal for the skill's purpose, it still represents external transmission of credentials and potentially sensitive workspace query results, so users need clear disclosure and scope expectations.

External Transmission

Medium
Category
Data Exfiltration
Content
NOTION_KEY=$(cat ~/.openclaw/workspace/secrets/notion_api_key.txt)
DATABASE_ID="YOUR_DATABASE_ID"  # Blog Series database

curl -s -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
91% confidence
Finding
This create-page example sends an Authorization header and user-supplied content to Notion, causing both credential use and remote data creation. The risk is not hidden exfiltration but undocumented external transmission and mutation of live workspace data.

External Transmission

Medium
Category
Data Exfiltration
Content
NOTION_KEY=$(cat ~/.openclaw/workspace/secrets/notion_api_key.txt)
ENTRY_ID="YOUR_ENTRY_ID"  # Minecraft series entry

curl -s -X PATCH "https://api.notion.com/v1/pages/$ENTRY_ID" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
90% confidence
Finding
This PATCH example performs an authenticated write to a remote Notion page. In the absence of a clear warning, a user may unknowingly modify production data while exposing page identifiers and metadata to an external service.

External Transmission

Medium
Category
Data Exfiltration
Content
NOTION_KEY=$(cat ~/.openclaw/workspace/secrets/notion_api_key.txt)
PAGE_ID="YOUR_ENTRY_ID"

curl -s -X PATCH "https://api.notion.com/v1/blocks/$PAGE_ID/children" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
90% confidence
Finding
Appending blocks to a page is an authenticated external write that changes remote content. The example is functionally legitimate, but it should disclose that it alters live page contents and sends the payload to Notion.

External Transmission

Medium
Category
Data Exfiltration
Content
SEVEN_DAYS_AGO=$(date -u -v-7d +"%Y-%m-%d")  # macOS
# For Linux: SEVEN_DAYS_AGO=$(date -u -d "7 days ago" +"%Y-%m-%d")

curl -s -X POST "https://api.notion.com/v1/data_sources/$DATA_SOURCE_ID/query" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
87% confidence
Finding
This query example sends an authenticated filter request to Notion and may retrieve recent workspace content and metadata. Although read-only, it still transmits credentials and potentially sensitive identifiers externally without an explicit warning.

External Transmission

Medium
Category
Data Exfiltration
Content
NOTION_KEY=$(cat ~/.openclaw/workspace/secrets/notion_api_key.txt)

# Get all Draft series
SERIES=$(curl -s -X POST "https://api.notion.com/v1/data_sources/YOUR_DATA_SOURCE_ID/query" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
90% confidence
Finding
The batch example first queries live draft entries using an authenticated request, exposing credentials and workspace record IDs to Notion. In context this is expected API usage, but the example should be clearly identified as operating on real remote data.

External Transmission

Medium
Category
Data Exfiltration
Content
# Update each to "In progress"
for entry_id in $SERIES; do
  curl -s -X PATCH "https://api.notion.com/v1/pages/$entry_id" \
    -H "Authorization: Bearer $NOTION_KEY" \
    -H "Notion-Version: 2025-09-03" \
    -H "Content-Type: application/json" \
Confidence
94% confidence
Finding
This loop performs repeated authenticated PATCH requests that bulk-modify remote pages, amplifying the impact of mistakes or misuse. The combination of external transmission and automated writes makes this more dangerous than a single-request example.

External Transmission

Medium
Category
Data Exfiltration
Content
NOTION_KEY=$(cat ~/.openclaw/workspace/secrets/notion_api_key.txt)
DATA_SOURCE_ID="YOUR_DATA_SOURCE_ID"  # Replace with your actual data source ID

curl -s -X POST "https://api.notion.com/v1/data_sources/$DATA_SOURCE_ID/query" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
88% confidence
Finding
This example performs an authenticated outbound request to Notion using a bearer token loaded from a local secrets file. While this is normal for the skill's purpose, it still represents external transmission of credentials and potentially sensitive workspace query results, so users need clear disclosure and scope expectations.

External Transmission

Medium
Category
Data Exfiltration
Content
NOTION_KEY=$(cat ~/.openclaw/workspace/secrets/notion_api_key.txt)
DATABASE_ID="YOUR_DATABASE_ID"  # Blog Series database

curl -s -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
91% confidence
Finding
This create-page example sends an Authorization header and user-supplied content to Notion, causing both credential use and remote data creation. The risk is not hidden exfiltration but undocumented external transmission and mutation of live workspace data.

External Transmission

Medium
Category
Data Exfiltration
Content
NOTION_KEY=$(cat ~/.openclaw/workspace/secrets/notion_api_key.txt)
ENTRY_ID="YOUR_ENTRY_ID"  # Minecraft series entry

curl -s -X PATCH "https://api.notion.com/v1/pages/$ENTRY_ID" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
90% confidence
Finding
This PATCH example performs an authenticated write to a remote Notion page. In the absence of a clear warning, a user may unknowingly modify production data while exposing page identifiers and metadata to an external service.

External Transmission

Medium
Category
Data Exfiltration
Content
NOTION_KEY=$(cat ~/.openclaw/workspace/secrets/notion_api_key.txt)
PAGE_ID="YOUR_ENTRY_ID"

curl -s -X PATCH "https://api.notion.com/v1/blocks/$PAGE_ID/children" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
90% confidence
Finding
Appending blocks to a page is an authenticated external write that changes remote content. The example is functionally legitimate, but it should disclose that it alters live page contents and sends the payload to Notion.

External Transmission

Medium
Category
Data Exfiltration
Content
SEVEN_DAYS_AGO=$(date -u -v-7d +"%Y-%m-%d")  # macOS
# For Linux: SEVEN_DAYS_AGO=$(date -u -d "7 days ago" +"%Y-%m-%d")

curl -s -X POST "https://api.notion.com/v1/data_sources/$DATA_SOURCE_ID/query" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
87% confidence
Finding
This query example sends an authenticated filter request to Notion and may retrieve recent workspace content and metadata. Although read-only, it still transmits credentials and potentially sensitive identifiers externally without an explicit warning.

External Transmission

Medium
Category
Data Exfiltration
Content
NOTION_KEY=$(cat ~/.openclaw/workspace/secrets/notion_api_key.txt)

# Get all Draft series
SERIES=$(curl -s -X POST "https://api.notion.com/v1/data_sources/YOUR_DATA_SOURCE_ID/query" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
90% confidence
Finding
The batch example first queries live draft entries using an authenticated request, exposing credentials and workspace record IDs to Notion. In context this is expected API usage, but the example should be clearly identified as operating on real remote data.

External Transmission

Medium
Category
Data Exfiltration
Content
# Update each to "In progress"
for entry_id in $SERIES; do
  curl -s -X PATCH "https://api.notion.com/v1/pages/$entry_id" \
    -H "Authorization: Bearer $NOTION_KEY" \
    -H "Notion-Version: 2025-09-03" \
    -H "Content-Type: application/json" \
Confidence
94% confidence
Finding
This loop performs repeated authenticated PATCH requests that bulk-modify remote pages, amplifying the impact of mistakes or misuse. The combination of external transmission and automated writes makes this more dangerous than a single-request example.

External Transmission

Medium
Category
Data Exfiltration
Content
SERIES_DB="YOUR_DATABASE_ID"

# Step 1: Create series entry
SERIES_ID=$(curl -s -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
Confidence
90% confidence
Finding
This advanced example creates a page via an authenticated request to Notion, transmitting the bearer token and supplied content to an external service. Because it creates persistent remote objects, users should be clearly warned that execution changes live workspace state.

External Transmission

Medium
Category
Data Exfiltration
Content
# Security: Properly escape title using jq
  local escaped_title=$(echo "$title" | jq -Rs '.')
  
  local response=$(curl -s -X POST "$BASE_URL/pages" \
    -H "Authorization: Bearer $NOTION_KEY" \
    -H "Notion-Version: $API_VERSION" \
    -H "Content-Type: application/json" \
Confidence
95% confidence
Finding
The create request builds JSON by shell string concatenation and inserts the unquoted database_id directly into the JSON body. Although the ID is regex-validated, the resulting payload is malformed for a JSON string field and this pattern of manual construction is fragile; if validation changes or adjacent fields are added later, it can become an injection primitive that sends unintended data to the Notion API.

External Transmission

Medium
Category
Data Exfiltration
Content
exit 1
  fi
  
  local response=$(curl -s -X PATCH "$BASE_URL/pages/$page_id" \
    -H "Authorization: Bearer $NOTION_KEY" \
    -H "Notion-Version: $API_VERSION" \
    -H "Content-Type: application/json" \
Confidence
99% confidence
Finding
The update request interpolates the property name directly into a JSON object without quoting or escaping it, while only the value is validated as JSON. An attacker controlling property can break the JSON structure or inject additional properties, causing unauthorized modifications to arbitrary page fields in Notion under the integration's privileges.

Session Persistence

Medium
Category
Rogue Agent
Content
}' | jq '.results[]'
```

### Create a Database Entry

```bash
DATABASE_ID="your_database_id"
Confidence
84% confidence
Finding
The 'Create a Database Entry' example demonstrates persistent remote modification of Notion data without a prominent caution that the action is live and durable. In an automation or agent setting, such examples can be executed unintentionally, causing unwanted records to be created in production workspaces and making cleanup or audit more difficult.

VirusTotal

66/66 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

No suspicious patterns detected.