Back to skill

Security audit

Alex Session Wrap-Up

Security checks for vulnerabilities and agentic risk

Overview

This session wrap-up skill is mostly coherent, but it can automatically push sensitive local files and send memory content to external AI services without enough user control.

Review before installing or running. At minimum, remove .env from git staging, stop sourcing dotenv files as shell code, add a dry-run and explicit confirmation before commit or push, restrict staged files to a narrow allowlist, require opt-in before external AI calls, redact memory content before sending it, and validate any model output before writing it to memory.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/session-wrap-up.sh:35
Finding

Automatic Commit and Push Can Expose Sensitive Workspace Data

Content
View full analysis
/dev/null 2>&1; then # Add only text/config files git add *.md *.txt *.json *.sh *.yaml *.yml *.env 2>/dev/null || true git add docs/* scripts/* skills/* memory/* 2>/dev/null || true git add AGENTS.md USER.md SOUL.md MEMORY.md TOOLS.md 2>/dev/null || true git add projects/*/README.md projects/*/notes/* 2>/dev/null || true if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then echo "Committing text/config changes..." git commit -m "Auto-wrap-up: $(date -Iseconds)" 2>/dev/null || true if git remote get-url origin >/dev/null 2>&1; then git push origin HEAD 2>/dev/null && echo " ✓ Pushed to origin" || echo " ⚠ Push failed" fi ``` ### Technical Analysis The script indiscriminately stages broad classes of workspace files, including `.env` files, memory records, user-related files, agent instruction files, and tool configuration. These file categories are particularly likely to contain API keys, personal information, internal project details, or privileged agent state. The subsequent `git commit` does not limit the commit to files staged by this invocation. Any content already in the Git index is also included. The resulting commit is automatically pushed to the repository configured as `origin`, without validating whether the destination is trusted, private, or expected and without presenting the staged diff for user approval. Although shipping work is part of the declared functionality, automatically transmitting sensitive agent and environment files exceeds the minimum privileges necessary to commit ordinary work products. ### Attack Path 1. A secret, private memory entry, or sensitive instruction is s ...[truncated 1224 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/session-wrap-up.sh:14
Finding

Arbitrary Shell Execution Through Sourced Environment File

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/session-wrap-up.sh:94
Finding

Unredacted Memory Entries Are Transmitted to Third-Party Model APIs

Content
View full analysis
/dev/null | head -20 || true) ``` ```bash if [[ -n "$LEARNINGS" && -n "${OPENAI_API_KEY:-}" ]]; then PATTERN_RESULT=$(curl -sS --max-time 30 "https://api.openai.com/v1/chat/completions" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"model\": \"$MODEL\", \"messages\": [{\"role\": \"user\", \"content\": \"$PROMPT\"}], \"max_tokens\": 300}" \ 2>/dev/null | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("choices",[{}])[0].get("message",{}).get("content","Error"))') \ || PATTERN_RESULT="API error" elif [[ -n "$LEARNINGS" && -n "${OPENROUTER_API_KEY:-}" ]]; then PATTERN_RESULT=$(curl -sS --max-time 30 "https://openrouter.ai/api/chat/v1/chat/completions" \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"model\": \"openai/gpt-4o-mini\", \"messages\": [{\"role\": \"user\", \"content\": \"$PROMPT\"}], \"max_tokens\": 300}" \ 2>/dev/null | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("choices",[{}])[0].get("message",{}).get("content","Error"))') \ || PATTERN_RESULT="API error" ``` ### Technical Analysis The script extracts up to 20 bullet-form memory entries and places them verbatim into a model prompt. If either supported API key is available, that prompt is transmitted to OpenAI or OpenRouter. No data classification, secret scanning, redaction, minimization, consent prompt, or preview occurs before transmission. Memory entries can contain conversation-derived personal information, credentials, private project information, internal URLs, or other material that the user did not ...[truncated 1296 chars]
Remediation
View remediation

T02 · Agent Memory Poisoning

Error
Location
scripts/session-wrap-up.sh:76
Finding

Untrusted Model Output Is Persisted Into Long-Term Agent Memory

Content
View full analysis
> "$MEMORY_FILE" echo "### Wrap-up Patterns ($TODAY)" >> "$MEMORY_FILE" echo "$PATTERN_RESULT" >> "$MEMORY_FILE" echo " ✓ Patterns saved" else ``` ### Technical Analysis The memory entries are interpolated directly into the instruction prompt without a strong trust boundary, structured data encoding, or an instruction that their contents must be treated only as quoted data. A malicious or compromised memory entry can therefore contain prompt-injection instructions intended to control the model response. The response is accepted as trustworthy based only on a few exact-string exclusions. Any other response is appended verbatim to the daily memory file. There is no schema enforcement, semantic validation, content filtering, provenance marker, or user approval. This creates a persistent trust-boundary violation: untrusted local memory influences a remote model, and the model's attacker-influenced output is then written back into long-term state that may be consumed by future sessions. ### Attack Path 1. An attacker or untrusted data source causes a bullet entry to be written into the current daily memory file. 2. The entry contains instructio ...[truncated 1075 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill description understates several high-risk behaviors: external API calls, remote git pushes, and loading secrets from a .env file. This mismatch can cause users or orchestrators to invoke the skill without understanding that code, metadata, or session-derived content may be exfiltrated or that remote state will be modified.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill lacks a clear warning that it may automatically commit changes, push to a remote repository, and modify local memory or agent files. These are significant side effects that can publish unfinished work, leak sensitive material, or alter future agent behavior without informed consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The markdown states that pattern detection uses external model providers but omits a privacy warning that session-derived learnings may be sent off-box. Because the skill scans conversation and memory entries, it may transmit sensitive project details, credentials, or personal data to third parties without the user's awareness.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

Reading a sibling .env file gives the script access to stored credentials and sensitive configuration that may be unrelated to wrap-up behavior. In combination with later network and git operations, this creates an unnecessary credential exposure surface and raises the consequences of any future script change or compromise.

Content

Scanner excerpt · scripts/session-wrap-up.sh (reported line 13)May include surrounding context.

sh
MODEL="gpt-4o-mini"

# Load env
if [[ -f "$WORKSPACE/../.env" ]]; then
  set -a
  source "$WORKSPACE/../.env"
  set +a

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The actual source command executes the contents of the .env file in the current shell, not merely parses key/value pairs. That means malformed or malicious content in the file could run arbitrary shell code under the user's account, making this more severe than passive credential reading.

Content

Scanner excerpt · scripts/session-wrap-up.sh (reported line 15)May include surrounding context.

sh
# Load env
if [[ -f "$WORKSPACE/../.env" ]]; then
  set -a
  source "$WORKSPACE/../.env"
  set +a
fi

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The script explicitly stages *.env files for commit. This can capture secrets such as API keys and service credentials into git history, and because the script may push to origin automatically, those secrets can be rapidly propagated to remote repositories and other collaborators.

Content

Scanner excerpt · scripts/session-wrap-up.sh (reported line 34)May include surrounding context.

sh
# Only commit text/config files, skip binaries and media
if git rev-parse --git-dir >/dev/null 2>&1; then
  # Add only text/config files
  git add *.md *.txt *.json *.sh *.yaml *.yml *.env 2>/dev/null || true
  git add docs/* scripts/* skills/* memory/* 2>/dev/null || true
  git add AGENTS.md USER.md SOUL.md MEMORY.md TOOLS.md 2>/dev/null || true
  git add projects/*/README.md projects/*/notes/* 2>/dev/null || true

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill description says it commits unpushed work, but the script also pushes to the remote origin automatically. That can exfiltrate local changes beyond the machine boundary, including notes, scripts, memory files, or accidentally staged sensitive data, and materially exceeds the stated behavior users might expect.

Content

No source excerpt is available for this finding.

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/session-wrap-up.sh (reported line 94)May include surrounding context.

sh
PATTERN_RESULT=""

if [[ -n "$LEARNINGS" && -n "${OPENAI_API_KEY:-}" ]]; then
  PATTERN_RESULT=$(curl -sS --max-time 30 "https://api.openai.com/v1/chat/completions" \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"model\": \"$MODEL\", \"messages\": [{\"role\": \"user\", \"content\": \"$PROMPT\"}], \"max_tokens\": 300}" \

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/session-wrap-up.sh (reported line 101)May include surrounding context.

sh
2>/dev/null | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("choices",[{}])[0].get("message",{}).get("content","Error"))') \
    || PATTERN_RESULT="API error"
elif [[ -n "$LEARNINGS" && -n "${OPENROUTER_API_KEY:-}" ]]; then
  PATTERN_RESULT=$(curl -sS --max-time 30 "https://openrouter.ai/api/chat/v1/chat/completions" \
    -H "Authorization: Bearer $OPENROUTER_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"model\": \"openai/gpt-4o-mini\", \"messages\": [{\"role\": \"user\", \"content\": \"$PROMPT\"}], \"max_tokens\": 300}" \

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares no explicit tool scope even though its documented behavior includes shell operations and network access. This weakens least-privilege controls and makes it easier for the skill to perform sensitive actions such as pushing code or sending data externally without clear user-approved boundaries.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The automatic trigger 'End of significant work session (optional)' is vague and can cause the skill to run without a clear, user-confirmed boundary. In this skill's context, accidental activation is dangerous because execution may commit files, push to remotes, and persist or transmit session-derived data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script sources an entire sibling .env file into its environment, importing every variable and secret whether needed or not. This expands the script's access to unrelated credentials and configuration, and because the same script later performs network transmission and git operations, over-broad secret loading increases the blast radius if the script misbehaves or is modified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script automatically commits and may push files without asking for confirmation. In a session-wrap-up context, users may not inspect staged files, so sensitive notes, environment files, or unintended workspace changes can be persisted locally or sent remotely without review.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The static URL match reflects a genuine outbound network destination used for data transfer. In this skill context, outbound transmission is more dangerous because it is tied to session memory analysis and happens in an automation script that may run routinely.

Content

Scanner excerpt · scripts/session-wrap-up.sh (reported line 94)May include surrounding context.

sh
PATTERN_RESULT=""

if [[ -n "$LEARNINGS" && -n "${OPENAI_API_KEY:-}" ]]; then
  PATTERN_RESULT=$(curl -sS --max-time 30 "https://api.openai.com/v1/chat/completions" \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"model\": \"$MODEL\", \"messages\": [{\"role\": \"user\", \"content\": \"$PROMPT\"}], \"max_tokens\": 300}" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The static URL match reflects a genuine outbound network destination used for data transfer. In this skill context, outbound transmission is more dangerous because it is tied to session memory analysis and happens in an automation script that may run routinely.

Content

Scanner excerpt · scripts/session-wrap-up.sh (reported line 94)May include surrounding context.

sh
PATTERN_RESULT=""

if [[ -n "$LEARNINGS" && -n "${OPENAI_API_KEY:-}" ]]; then
  PATTERN_RESULT=$(curl -sS --max-time 30 "https://api.openai.com/v1/chat/completions" \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"model\": \"$MODEL\", \"messages\": [{\"role\": \"user\", \"content\": \"$PROMPT\"}], \"max_tokens\": 300}" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script sends session memory contents to external AI providers for pattern detection without explicit consent or a meaningful warning. Session memory can contain sensitive prompts, internal notes, project details, or user data, so transmitting it off-host creates a privacy and data-governance risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

This branch sends the same session-derived content to OpenRouter, again causing third-party disclosure of local memory content. The danger is heightened because it is an alternate path, so users may not realize their data could be sent to different providers depending on available keys.

Content

Scanner excerpt · scripts/session-wrap-up.sh (reported line 101)May include surrounding context.

sh
2>/dev/null | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("choices",[{}])[0].get("message",{}).get("content","Error"))') \
    || PATTERN_RESULT="API error"
elif [[ -n "$LEARNINGS" && -n "${OPENROUTER_API_KEY:-}" ]]; then
  PATTERN_RESULT=$(curl -sS --max-time 30 "https://openrouter.ai/api/chat/v1/chat/completions" \
    -H "Authorization: Bearer $OPENROUTER_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"model\": \"openai/gpt-4o-mini\", \"messages\": [{\"role\": \"user\", \"content\": \"$PROMPT\"}], \"max_tokens\": 300}" \