Back to skill

Security audit

Notion Tasks Blocks

Security checks for vulnerabilities and agentic risk

Overview

This skill transparently manages a configured Notion checklist page and does not show hidden, persistent, destructive, or unrelated behavior.

Install only if you are comfortable granting a Notion integration access to the configured task page. Use a dedicated Notion token shared only with that page, rotate it if exposed, and avoid running this on shared systems where other local users can inspect process command lines.

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_tasks_blocks.sh:12
Finding

Sensitive Notion credentials and task data exposed through process command-line arguments

Content
View full analysis
(arr||[]).map(x => x?.plain_text || x?.text?.content || "").join("").trim(); const todos = (j.results||[]) .filter(b => b.type === "to_do") .map((b, i) => ({ index: i + 1, id: b.id, checked: !!b.to_do?.checked, text: getText(b.to_do?.rich_text) })); console.log(JSON.stringify({todos, total: todos.length})); ' "$raw" } ``` ```bash todos="$(get_todos_json)" block_id="$(node -e ' const j = JSON.parse(process.argv[1]); const idx = Number(process.argv[2]); const t = (j.todos||[]).find(x => x.index === idx); if (!t) process.exit(2); process.stdout.write(t.id); ' "$todos" "$idx" 2>/dev/null || true)" ``` ### Technical Analysis The script places sensitive information directly in child-process argument vectors: 1. The Notion integration bearer token is expanded into a `curl` header argument. 2. The complete Notion API response is passed to Node.js through `process.argv[1]`. 3. The processed task list, including task text and block identifiers, is also passe ...[truncated 2008 chars]
Remediation
View remediation
raw += chunk); process.stdin.on("end", () => { const j = JSON.parse(raw); // Validate and process the response. }); ' ``` 2. **Avoid placing the authorization header directly in `curl` arguments** Use a protected curl configuration supplied through standard input: ```bash printf '%s\n' \ "header = \"Authorization: Bearer $NOTION_TOKEN\"" \ "header = \"Notion-Version: $version\"" \ 'header = "Content-Type: application/json"' | curl -sS --config - -X "$method" "$url" ``` Verify the target platform's `curl` behavior and ensure configuration contents are not copied into diagnostic logs. 3. **Transmit request payloads through standard input** Replace `--data "$data"` with a standard-input form such as: ```bash printf '%s' "$data" | curl ... --data-binary @- ``` This keeps task content out of the argument vector. 4. **Minimize credential privileges** Use a dedicated Notion integration token and share only the required task page with that integration. Revoke and rotate the token if local disclosure is suspected. 5. **Harden local process visibility** Where supported, restrict cross-user process inspection. This is defense in depth and should not replace removing secrets from command-line arguments. 6. **Avoid insecure temporary-file alternatives** If temporary files are unavoidable, create them with restrictive permissions, store them in a trusted directory, register cleanup traps, and securely remove them after use. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes a shell wrapper but does not declare any tool scope such as allowed-tools or permissions, so an agent may execute shell access without an explicit capability boundary. In a skill that takes user-provided arguments like task text and indexes, this weakens least-privilege controls and increases the chance of unintended or unsafe command execution paths.

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/notion_tasks_blocks.sh (reported line 7)May include surrounding context.

sh
: "${NOTION_TOKEN:?Missing NOTION_TOKEN}"
: "${NOTION_TASKS_PAGE_ID:?Missing NOTION_TASKS_PAGE_ID}"

api="https://api.notion.com/v1"
version="2022-06-28"
cmd="${1:-}"
shift || true

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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/notion_tasks_blocks.sh (reported line 17)May include surrounding context.

sh
local url="$1"; shift
  local data="${1:-}"
  if [[ -n "$data" ]]; then
    curl -sS -X "$method" "$url" \
      -H "Authorization: Bearer $NOTION_TOKEN" \
      -H "Notion-Version: $version" \
      -H "Content-Type: application/json" \

Static analysis

No suspicious patterns detected.