Back to skill

Security audit

Notion Enhanced

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real Notion integration, but its agent examples and helper scripts include unsafe command and credential-handling patterns that deserve review before installation.

Install only if you are comfortable giving the skill read/write access to the Notion pages and databases you share. Use a dedicated Notion integration with the smallest possible page/database scope, avoid running the documented exec examples with untrusted titles or JSON values, prefer argument-array execution or direct API calls, review setup-wizard.sh before use, and protect ~/.openclaw/.env with restrictive permissions.

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

T09 · Insecure Skill Coding Practices

Error
Location
templates/examples/content-scout-example.js:53
Finding

Shell Command Injection in Agent Integration Examples

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
setup-wizard.sh:14
Finding

Unsafe Import of Arbitrary Variables from the OpenClaw Credential File

Content
View full analysis
/dev/null 2>&1; then echo "✅ Connected to Notion!" else ``` ### Technical Analysis The setup wizard only needs `NOTION_TOKEN`, but it imports every non-comment entry from `~/.openclaw/.env` into the process environment. The `export $(cat ... | xargs)` construction is not a valid dotenv parser. It is sensitive to whitespace, quoting, wildcard expansion, malformed entries, and values containing special characters. It can alter unrelated variables that affect later commands. Of particular concern are runtime-control variables such as: - `PATH`, which controls which `node` executable is selected. - `NODE_OPTIONS`, which can make Node load additional modules or apply dangerous runtime options. - `NODE_PATH`, which affects module resolution. - Proxy and TLS-related variables, which may redirect or weaken network behavior. This behavior exceeds minimum privilege because the wizard only needs to obtain one credential. Importing unrelated secrets and process-control settings is unnecessary. The shell does not generally reparse command separators produced solely by command substitution as new shell operators. The primary exploitation concern is therefore environment poisoning and unsafe parsing, rather than direct execution of literal shell syntax embedded in the file. ### Attack Path 1. Another local process, installed Skill, synchronization mechanism, or compromised configuration source modifies `~/.openclaw/.env`. 2. It adds a runtime-control entry, for example: ```text NODE_OPTIONS=--require=/path/to/attacker-contr ...[truncated 1361 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
notion-cli.js:136
Finding

Predictable Shared Temporary File Allows Symlink Overwrite and Identifier Disclosure

Content
View full analysis
0) { const mapping = {}; simplified.forEach(entry => { mapping[`#${entry.entry_number}`] = entry.id; }); // Save to temp file for potential ID lookup const fs = require('fs'); const os = require('os'); const path = require('path'); const mappingPath = path.join(os.tmpdir(), 'notion-entry-mapping.json'); fs.writeFileSync(mappingPath, JSON.stringify(mapping, null, 2)); } ``` ### Technical Analysis The CLI writes Notion page mappings to a fixed filename under the system temporary directory: ```text /tmp/notion-entry-mapping.json ``` The filename is shared and predictable. `fs.writeFileSync()` uses normal write/truncate behavior, follows symbolic links, and does not request exclusive creation. The code also does not create a private per-user directory or explicitly set restrictive permissions. On a multi-user system, another local user may create the path before the victim runs the command. If the path is a symbolic link, the victim process follows it and overwrites the linked file, provided that the victim has permission to write the target. The generated file also contains full Notion page UUID mappings. Depending on the process umask and temporary-directory environment, those identifiers may be readable by other local users. Although page UUIDs do not replace authentication, they reveal workspace metadata and can assist later attacks when combined with a compromised token. The mapping file does not appear to be consumed elsewhere in the reviewed implementation, so the write is unnecessary for the declared CLI behavior. ### Attack Path 1. An attacker with local access predicts the fixed temporary path. 2. Before the victim runs the CLI, the attacker create ...[truncated 1278 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (33)

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

3. Configure

bash
# Add to ~/.openclaw/.env
NOTION_TOKEN=secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

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

3. Configure

bash
# Add to ~/.openclaw/.env
NOTION_TOKEN=secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

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 · notion-cli.js (reported line 507)May include surrounding context.

js
### 3. Configure

```bash
# Add to ~/.openclaw/.env
NOTION_TOKEN=secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

Credential Access

High
Category
Privilege Escalation
Confidence
71% confidence
Finding

The command echo "NOTION_TOKEN=..." >> ~/.openclaw/.env encourages writing a live credential directly into a plaintext file via shell history-visible commands. While not exfiltration, it increases exposure risk through shell history, local file disclosure, and accidental mishandling of secrets in shared environments.

Content

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

md
npm install

# 2. Configure token
echo "NOTION_TOKEN=secret_xxxxxxxxxx" >> ~/.openclaw/.env

# 3. Test connection
node notion-cli.js test

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The script loads and exports every key/value from ~/.openclaw/.env using command substitution and xargs. This is dangerous because a malformed or attacker-influenced .env file can inject unintended shell parsing behavior, and it also unnecessarily exposes all secrets from that file to child processes instead of only the Notion token.

Content

Scanner excerpt · setup-wizard.sh (reported line 14)May include surrounding context.

sh
# Check for NOTION_TOKEN
if [ -z "$NOTION_TOKEN" ]; then
    if [ -f "$HOME/.openclaw/.env" ]; then
        export $(cat "$HOME/.openclaw/.env" | grep -v '#' | xargs)
    fi
fi

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

This line performs the actual bulk export of the .env file into the environment. If the file contains additional credentials or crafted content, those values become available to any subprocess launched later, increasing exposure of secrets and creating risk from unsafe shell parsing of untrusted configuration content.

Content

Scanner excerpt · setup-wizard.sh (reported line 15)May include surrounding context.

sh
# Check for NOTION_TOKEN
if [ -z "$NOTION_TOKEN" ]; then
    if [ -f "$HOME/.openclaw/.env" ]; then
        export $(cat "$HOME/.openclaw/.env" | grep -v '#' | xargs)
    fi
fi

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 · setup-wizard.sh (reported line 210)May include surrounding context.

sh
import * as path from "path";

// Load env from common locations
dotenv.config({ path: path.join(process.env.HOME || "", ".openclaw", ".env") });
dotenv.config({ path: path.join(process.env.HOME || "", ".env") });
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 · src/cli.ts (reported line 10)May include surrounding context.

ts
import * as path from "path";

// Load env from common locations
dotenv.config({ path: path.join(process.env.HOME || "", ".openclaw", ".env") });
dotenv.config({ path: path.join(process.env.HOME || "", ".env") });
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 · src/cli.ts (reported line 11)May include surrounding context.

ts
import * as path from "path";

// Load env from common locations
dotenv.config({ path: path.join(process.env.HOME || "", ".openclaw", ".env") });
dotenv.config({ path: path.join(process.env.HOME || "", ".env") });
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 · templates/examples/README.md (reported line 51)May include surrounding context.

Then load in scripts:

javascript
require('dotenv').config({ 
  path: require('path').join(require('os').homedir(), '.openclaw', '.env') 
});

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README promotes workspace search, reading, writing, and content management across any pages explicitly shared with the integration, but it does not clearly warn users that granting access enables both data exposure and data modification by the agent. In an agentic context, users may underestimate how much content can be searched or altered once a database or parent page is shared, increasing the risk of unintended disclosure or destructive writes.

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

Manual Install

1. Create Notion Integration

text
notion.so/my-integrations → New integration → Copy token

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill documents access to environment-based credentials (NOTION_TOKEN) and execution of a local CLI, but it does not declare any explicit tool scope such as allowed tools or permissions. In agent environments, missing scope declarations can permit broader-than-expected command or environment access, increasing the chance of unintended secret exposure or misuse.

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

md
---
name: notion
version: 0.1.0
description: Integrate with Notion workspaces to read pages, query databases, create entries, and manage content. Perfect for knowledge bases, project tracking, content calendars, CRMs, and collaborative documentation. Works with any Notion page or database you explicitly share with the integration.
---

# Notion Integration

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This section instructs the agent to create, update, and append content in a live Notion workspace, but it does not clearly warn that these operations modify remote user data. In an agentic context, that omission can lead to accidental writes, overwrites, or content corruption if actions are taken without explicit user confirmation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The test command enumerates accessible Notion pages/databases and prints titles and partial IDs directly to stdout with no warning, confirmation, or output-minimization. In agent or shared-terminal contexts, this can expose sensitive workspace metadata, project names, and identifiers to logs, transcripts, or unintended viewers even though the API call itself is legitimate.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

When --numbered is used, the script writes a page-ID mapping file into the system temp directory without notifying the user or applying access controls. Temp directories are often readable by other local processes/users depending on platform and configuration, so this creates unintended local persistence of sensitive identifiers that may later be harvested from disk.

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 · setup-wizard.sh (reported line 24)May include surrounding context.

sh
echo ""
    echo "Setup steps:"
    echo "1. Go to https://www.notion.so/my-integrations"
    echo "2. Create new integration"
    echo "3. Copy the token (starts with 'secret_')"
    echo "4. Add to ~/.openclaw/.env:"
    echo "   NOTION_TOKEN=secret_your_token_here"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The test command prints titles, IDs, and URLs for accessible Notion pages and databases directly to stdout, which can expose sensitive workspace metadata to terminal logs, calling processes, CI output, or other users on shared systems. While intended as a connectivity check, this disclosure can aid reconnaissance by revealing internal structure and identifiers that make follow-on access or social engineering easier.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

The database query method retrieves potentially sensitive workspace records from Notion, and similar remote data access appears in this skill without any user-facing notice. Because the code performs network-backed access to user or organizational data with no prompt, logging, or documented warning in this file, users may be unaware of the scope of data being fetched.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

This method retrieves a page and its child blocks from Notion, which may include sensitive user or organizational content. The file contains no confirmation, print/log notice, or inline user warning indicating that remote content will be accessed and returned.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% 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 · notion-cli.js (reported line 481)May include surrounding context.

js
return { page, blocks: blocks.results };
  }

  // Add entry to database
  async addEntry(databaseId: string, properties: any) {
    const cleanId = this.cleanId(databaseId);
    return await this.client.pages.create({

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% 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 · src/index.ts (reported line 36)May include surrounding context.

ts
return { page, blocks: blocks.results };
  }

  // Add entry to database
  async addEntry(databaseId: string, properties: any) {
    const cleanId = this.cleanId(databaseId);
    return await this.client.pages.create({

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The search method sends the provided query to Notion via an external network call, which can disclose user-entered text to a third-party service. In this file, there is no confirmation prompt, warning, or user-facing logging indicating that the query will be transmitted off-system.

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 · templates/README.md (reported line 198)May include surrounding context.

md
Update select/multi_select options to match your workflow:
- Add/remove platforms to match your social presence
- Adjust project statuses for your process
- Create custom tags for your niche

### Creating Views

Static analysis

No suspicious patterns detected.