T09 · Insecure Skill Coding Practices
- 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. ]]>
