Back to skill

Security audit

4to1 Planner Bak

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent planning assistant, but its setup/status scripts handle credentials unsafely and can execute injected shell code from its config file.

Review before installing. Use the local Markdown backend or a tightly scoped integration if possible, do not paste tokens from untrusted sources, restrict permissions on ~/.config/4to1/config, and avoid running status.sh until the config loading is changed to parse data without source.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/status.sh:12
Finding

Arbitrary Command Execution Through Sourced Configuration

Content
View full analysis
> "$CONFIG_DIR/config" echo "" echo "5. In Notion, create or open the page where you want your planning hub" echo "6. Click ··· → Connections → select '4To1 Planner'" echo "7. Copy the page ID from the URL (the 32-char hex string after the page name)" echo "" read -p "Paste the parent page ID: " parent_page echo "NOTION_PARENT_PAGE=$parent_page" >> "$CONFIG_DIR/config" ``` `scripts/setup.sh:51-52`: ```bash read -p "Paste your Todoist API token: " todoist_key echo "TODOIST_API_KEY=$todoist_key" >> "$CONFIG_DIR/config" ``` ### Technical Analysis The setup script accepts API keys and a page identifier as untrusted interactive input and writes them verbatim into `~/.config/4to1/config`. The status script subsequently loads that file with Bash's `source` command. A sourced file is executable shell code, not a passive configuration format. Consequently, shell constructs embedded in a saved value—including command substitutions, additional commands, redirections, and function definitions—are interpreted when `status.sh` runs. Quoting `"$CONFIG"` only protects the configuration file path; it does not prevent execution of content inside that file. For example, a value containing a command substitution can result in a configuration entry resembling: ```bash TODOIST_API_KEY=$(attacker-controlled-command) ``` The command substitution is not executed merely because the variable is expanded by `echo` during setup, but it is written into the configuration file and later executed when Bash sources that fi ...[truncated 1499 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup.sh:13
Finding

API Credentials Stored Without Enforced Access Permissions

Content
View full analysis
"$CONFIG_DIR/config" echo "" echo "📝 Notion Setup:" echo "1. Go to https://www.notion.so/my-integrations" echo "2. Click '+ New integration'" echo "3. Name it '4To1 Planner', select your workspace" echo "4. Copy the 'Internal Integration Secret' (starts with ntn_)" echo "" read -p "Paste your Notion API key: " notion_key echo "NOTION_API_KEY=$notion_key" >> "$CONFIG_DIR/config" echo "" echo "5. In Notion, create or open the page where you want your planning hub" echo "6. Click ··· → Connections → select '4To1 Planner'" echo "7. Copy the page ID from the URL (the 32-char hex string after the page name)" echo "" read -p "Paste the parent page ID: " parent_page echo "NOTION_PARENT_PAGE=$parent_page" >> "$CONFIG_DIR/config" ``` `scripts/setup.sh:45-52`: ```bash echo "BACKEND=todoist" > "$CONFIG_DIR/config" echo "" echo "📋 Todoist Setup:" echo "1. Go to https://app.todoist.com/app/settings/integrations/developer" echo "2. Copy your API token" echo "" read -p "Paste your Todoist API token: " todoist_key echo "TODOIST_API_KEY=$todoist_key" >> "$CONFIG_DIR/config" ``` ### Technical Analysis The setup script stores long-lived Notion and Todoist bearer credentials in a plaintext file without setting a restrictive `umask` or explicitly applying permissions to the configuration directory and file. The resulting access modes depend on the caller's existing environment. Under permissive defaults, the directory or configuration file may be readable by other local accounts. The API keys are bearer credentials, so anyone who obtains a token can exercise the permissions granted to the corresponding Notion integration or Todoist account without needi ...[truncated 1514 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (38)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/status.sh (reported line 21)May include surrounding context.

sh
case $BACKEND in
  notion)
    echo "Testing Notion connection..."
    RESULT=$(curl -s -o /dev/null -w "%{http_code}" \
      "https://api.notion.com/v1/users/me" \
      -H "Authorization: Bearer $NOTION_API_KEY" \
      -H "Notion-Version: 2025-09-03")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README promotes automatic tracking where the AI 'reads your Notion/Todoist' but does not warn users that connecting these services grants access to potentially sensitive productivity data such as tasks, calendars, projects, and notes. This omission weakens informed consent and can lead users to authorize data access without understanding the privacy implications.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README advertises very broad natural-language triggers such as 'What should I focus on today?' and 'How am I doing?', which overlap with common assistant requests and do not clearly signal when this specific skill should activate. In an agent ecosystem, ambiguous routing can cause the skill to be invoked unintentionally, leading to inappropriate access to planning data or external integrations when the user did not explicitly intend to use this tool.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The installation guidance suggests the generic phrase 'Help me set up my 4to1 planning system,' which is still broad enough to collide with ordinary planning or productivity requests in a shared agent environment. Weak activation boundaries increase the chance of accidental routing to this skill, potentially exposing connected service data or causing unrequested setup actions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill declares no explicit tool scope even though it clearly instructs use of shell commands, file writes, and network-capable utilities like curl and python3. Without narrow tool restrictions, an agent may execute powerful local and external actions beyond what the user reasonably expects, increasing the chance of unauthorized data writes or exfiltration.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The activation phrases are broad and match common planning requests, so the skill may trigger in ordinary conversations where the user did not intend to connect external services or persist private planning data. That increases the risk of surprise tool use, credential setup prompts, and unintended storage of sensitive personal goals and routines.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill does not prominently warn users that highly personal planning data may be stored in Notion, Todoist, Google, or local files. Because the collected content includes long-term goals, habits, priorities, and review notes, omission of a storage/transmission warning undermines informed consent and can expose sensitive personal information.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
98% confidence
Finding

The skill instructs users to store long-lived API keys in a plaintext config file under the home directory. Plaintext credential persistence materially increases the risk of token theft by other local processes, accidental disclosure, or inclusion in backups, and those tokens authorize access to external services holding personal planning data.

Content

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

Option 1: Notion (Recommended)

bash
# 1. Create a Notion integration at https://www.notion.so/my-integrations
# 2. Copy the API key (starts with ntn_)
# 3. Store it:
mkdir -p ~/.config/4to1

Session Persistence

Medium
Category
Rogue Agent
Confidence
86% confidence
Finding

This workflow depends on reading persisted credentials and remote identifiers from local config and then using them to create remote resources. The persistence itself is security-relevant because it normalizes long-term storage of sensitive access material and operational identifiers without discussing protection or lifecycle management.

Content

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

md
NOTION_KEY=$(grep NOTION_API_KEY ~/.config/4to1/config | cut -d= -f2)
PARENT_PAGE=$(grep NOTION_PARENT_PAGE ~/.config/4to1/config | cut -d= -f2)

# Create the 4To1 Planning Hub page
curl -s -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

This command sends planning workspace data to the Notion API using a bearer token, which is an external transmission of user data and metadata. In context this is expected functionality, but it is still security-relevant because it persists potentially sensitive personal planning information to a third-party service and depends on stored credentials.

Content

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

md
PARENT_PAGE=$(grep NOTION_PARENT_PAGE ~/.config/4to1/config | cut -d= -f2)

# Create the 4To1 Planning Hub page
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" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

This command sends planning workspace data to the Notion API using a bearer token, which is an external transmission of user data and metadata. In context this is expected functionality, but it is still security-relevant because it persists potentially sensitive personal planning information to a third-party service and depends on stored credentials.

Content

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

md
PARENT_PAGE=$(grep NOTION_PARENT_PAGE ~/.config/4to1/config | cut -d= -f2)

# Create the 4To1 Planning Hub page
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" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This Notion database creation call writes structured planning data to an external service. The danger is primarily privacy and unauthorized persistence risk if triggered without clear consent, not malicious payload delivery.

Content

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

md
}"

# Create Projects database (tracks items across all 4 layers)
curl -s -X POST "https://api.notion.com/v1/databases" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This command creates a sprint log database in Notion, persisting review and productivity information to a third party. Sprint logs can reveal behavioral patterns, workload, and health/energy signals, making privacy impact nontrivial.

Content

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

md
}"

# Create Sprint Log database (2-week tracking cycles)
curl -s -X POST "https://api.notion.com/v1/databases" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

This command creates projects in Todoist via authenticated API calls, transmitting user planning structure to an external service. While aligned with the skill purpose, it still exposes user task taxonomy and requires network write capability, so unexpected activation or misuse could create or modify third-party data without sufficient user intent.

Content

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

md
TODOIST_KEY=$(grep TODOIST_API_KEY ~/.config/4to1/config | cut -d= -f2)

for project in "🔭 4-Year Vision" "📊 3-Month Milestones" "🏃 2-Week Sprint" "✅ Daily Tasks" "🚫 Not-To-Do"; do
  curl -s -X POST "https://api.todoist.com/rest/v2/projects" \
    -H "Authorization: Bearer $TODOIST_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"name\": \"$project\"}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

This command creates projects in Todoist via authenticated API calls, transmitting user planning structure to an external service. While aligned with the skill purpose, it still exposes user task taxonomy and requires network write capability, so unexpected activation or misuse could create or modify third-party data without sufficient user intent.

Content

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

md
TODOIST_KEY=$(grep TODOIST_API_KEY ~/.config/4to1/config | cut -d= -f2)

for project in "🔭 4-Year Vision" "📊 3-Month Milestones" "🏃 2-Week Sprint" "✅ Daily Tasks" "🚫 Not-To-Do"; do
  curl -s -X POST "https://api.todoist.com/rest/v2/projects" \
    -H "Authorization: Bearer $TODOIST_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"name\": \"$project\"}"

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

The local backend creates persistent directories and files containing long-term goals, habits, reviews, and task history on disk. That is expected behavior, but it still creates a privacy risk if users are not warned, if permissions are lax, or if the skill activates unexpectedly and writes sensitive data locally.

Content

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

bash
echo "BACKEND=local" > ~/.config/4to1/config
echo "LOCAL_DIR=~/4to1-plans" >> ~/.config/4to1/config
mkdir -p ~/4to1-plans/{vision,milestones,sprints,daily,not-to-do}

Core Commands

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

The Notion search request transmits a query and authenticated access to remote content, enabling discovery and retrieval of planning-related data from a third-party service. In a broadly-triggered skill, such reads can expose sensitive information unexpectedly even if no new data is written.

Content

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

md
NOTION_KEY=$(grep NOTION_API_KEY ~/.config/4to1/config | cut -d= -f2)

# Search planning pages
curl -s -X POST "https://api.notion.com/v1/search" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

The Notion search request transmits a query and authenticated access to remote content, enabling discovery and retrieval of planning-related data from a third-party service. In a broadly-triggered skill, such reads can expose sensitive information unexpectedly even if no new data is written.

Content

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

md
NOTION_KEY=$(grep NOTION_API_KEY ~/.config/4to1/config | cut -d= -f2)

# Search planning pages
curl -s -X POST "https://api.notion.com/v1/search" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This authenticated Notion database query reads project data by layer from a remote service. In the context of a planning assistant, those records may contain sensitive life and work goals, so remote reads should be treated as security-relevant.

Content

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

md
-d '{"query": "4To1"}'

# Query projects by layer
curl -s -X POST "https://api.notion.com/v1/databases/{db_id}/query" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

This PATCH request updates progress and status in Notion, which can modify user records on a third-party platform. The risk is unauthorized or surprising data modification if the skill activates too broadly or infers updates without user approval.

Content

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

md
]}}'

# Update progress
curl -s -X PATCH "https://api.notion.com/v1/pages/{page_id}" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

Creating sprint log entries is a form of durable session persistence of behavioral and reflective data. In this skill's context, those entries may include performance metrics and personal notes, which become sensitive history if retained remotely without clear retention expectations.

Content

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

md
-H "Content-Type: application/json" \
  -d '{"properties": {"Progress": {"number": 0.75}, "Status": {"select": {"name": "Active"}}}}'

# Create sprint log entry
curl -s -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This call creates a sprint review log entry in Notion, transmitting reflective notes and completion metrics externally. Such review entries can contain sensitive personal performance data and should not be created implicitly.

Content

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

md
-d '{"properties": {"Progress": {"number": 0.75}, "Status": {"select": {"name": "Active"}}}}'

# Create sprint log entry
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" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

These Todoist API calls retrieve project and task data from an external service using a bearer token. Although necessary for functionality, they expand exposure of personal planning data and should not occur from ambiguous activation alone.

Content

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

md
TODOIST_KEY=$(grep TODOIST_API_KEY ~/.config/4to1/config | cut -d= -f2)

# Get all projects
curl -s "https://api.todoist.com/rest/v2/projects" -H "Authorization: Bearer $TODOIST_KEY"

# Get active tasks in a project
curl -s "https://api.todoist.com/rest/v2/tasks?project_id={id}" -H "Authorization: Bearer $TODOIST_KEY"

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

These Todoist API calls retrieve project and task data from an external service using a bearer token. Although necessary for functionality, they expand exposure of personal planning data and should not occur from ambiguous activation alone.

Content

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

md
TODOIST_KEY=$(grep TODOIST_API_KEY ~/.config/4to1/config | cut -d= -f2)

# Get all projects
curl -s "https://api.todoist.com/rest/v2/projects" -H "Authorization: Bearer $TODOIST_KEY"

# Get active tasks in a project
curl -s "https://api.todoist.com/rest/v2/tasks?project_id={id}" -H "Authorization: Bearer $TODOIST_KEY"

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This Todoist task fetch reads tasks for a specified project from an external account. Task contents often include confidential project names, deadlines, and descriptions, so even read-only access is security-relevant.

Content

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

md
curl -s "https://api.todoist.com/rest/v2/projects" -H "Authorization: Bearer $TODOIST_KEY"

# Get active tasks in a project
curl -s "https://api.todoist.com/rest/v2/tasks?project_id={id}" -H "Authorization: Bearer $TODOIST_KEY"

# Create task linked to sprint
curl -s -X POST "https://api.todoist.com/rest/v2/tasks" \

Static analysis

No suspicious patterns detected.