T01 · Skill Instruction Hijacking
- Location
tools/skill_writer.py:28- Finding
Persistent instruction hijacking through globally installed generated Skills
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is mostly coherent, but it collects and persists sensitive coworker data and generated agent instructions with insufficient scoping and consent controls.
Install only if you have authorization and the teammate's consent to use their communications and work artifacts. Prefer manual, approved source files; avoid private-channel Slack scopes unless explicitly approved; use fine-grained read-only GitHub tokens; secure or avoid persisted tokens; review generated SKILL.md files before global installation; do not share raw knowledge files or generated personas without a privacy review.
tools/skill_writer.py:28Persistent instruction hijacking through globally installed generated Skills
tools/slack_collector.py:36Slack Bot OAuth token is stored in plaintext without enforced file permissions
tools/slack_collector.py:100Slack collector requests and scans private channels beyond minimum necessary scope
tools/skill_writer.py:83Unvalidated teammate slug allows filesystem path traversal and arbitrary file placement
requirements.txt:1Unbounded Slack SDK dependency permits unreproducible and unsafe future package resolution
The guide instructs creation of a GitHub personal access token with potentially broad repository access but does not emphasize least privilege, secure storage, rotation, or the consequences of compromise. In a skill that automates extraction of engineering knowledge from private repos, a mishandled PAT could enable unauthorized access to source code and associated metadata across private projects.
Pulls PRs, code reviews, commit messages, and issue comments.
**Step 1: Create a Personal Access Token**
1. Go to [github.com/settings/tokens](https://github.com/settings/tokens) → **Generate new token (classic)**
2. Select scope: `repo` (private repos) or `public_repo` (public only)
The declared description promises a system for distilling a teammate into an AI skill by collecting data from communication and code platforms and generating structured outputs like a Work Skill and 5-layer Persona. The supplied code does none of that. It only parses Confluence HTML/ZIP exports into plain text and saves them to a file, with optional filtering by a target name. This is a materially different primary purpose and accesses a different resource type than described, so it is a clear mismatch.
This is a clear mismatch. The declared description promises a knowledge-capture/AI-teammate creation capability based on workplace platforms like Slack, Teams, and GitHub, including persona generation and continuous evolution. The supplied code does none of that. It simply parses local email files, filters by sender, extracts message text, and saves results to a text file. Its primary purpose, inputs, outputs, and accessed resources are materially different from the declared purpose.
The declared description focuses on knowledge capture and AI teammate creation from external collaboration sources like Slack, Teams, and GitHub, including persona/work-skill generation and continuous evolution. The actual code does none of that. It does not collect data from external services, generate a skill or persona, or evolve anything. Instead, it packages already-existing teammate files for portability and can also import such packages. This is a materially different primary purpose and introduces undeclared file packaging/import capabilities, so this should be flagged as a mismatch.
The description promises a broader teammate-distillation workflow: multi-source collection (Slack, Teams, GitHub) plus synthesis into an AI skill/persona that evolves over time. The actual code only performs one narrow subtask: collecting GitHub PRs, review comments, and issue comments for a username and saving them to files. While GitHub collection is consistent with one part of the declared description, the primary purpose of the code chunk is data harvesting/export, not distilling a teammate into an AI skill. The major advertised outputs and behaviors are absent, so this is a material description-behavior mismatch.
The declared description promises a teammate-distillation skill focused on aggregating collaboration-platform data and generating an AI teammate artifact. The supplied code does something materially different: it only parses local Notion export files and writes extracted document text to an output file. While Notion content extraction could conceivably be a supporting subcomponent of a broader teammate-distillation pipeline, this chunk by itself lacks the described primary behavior, data sources, and outputs. Therefore this is a clear description-behavior mismatch.
The declared purpose focuses on teammate knowledge capture and AI skill/persona generation from collaboration platforms like Slack, Teams, and GitHub. The actual code does none of that: it does not connect to external services, collect teammate data, generate skills/personas, or implement continuous evolution. Instead, it scans local files for sensitive data such as emails, phone numbers, API tokens, private keys, and passwords, and can redact them. This is a materially different primary purpose and introduces undeclared capabilities related to privacy/security scanning and file modification.
The declared description centers on creating an AI version of a teammate from workplace knowledge sources like Slack, Teams, and GitHub. The supplied code does something materially different: it parses exported issue tracker data from JIRA or Linear for a named user and writes issue summaries to a text file. There is no functionality for collecting Slack/Teams/GitHub data, synthesizing a work skill or 5-layer persona, or continuously evolving a teammate model. This is a clear purpose and capability mismatch.
The description presents this skill as an end-to-end teammate distillation system that gathers data from Slack/Teams/GitHub and generates an AI teammate profile with ongoing evolution. The supplied code does not perform any data collection, analysis, synthesis, or model/persona generation. Instead, it is a utility that writes provided meta/work/persona content into a directory structure, regenerates a templated SKILL.md, updates versions and timestamps, applies simple text patches, and lists existing skills. While 'continuous evolution' is loosely related to the update/versioning behavior, the core declared capabilities are absent, and the actual code's primary purpose is file writing and bookkeeping.
The description claims a broader teammate-distillation system that auto-collects from Slack, Teams, and GitHub and then generates higher-level AI-skill/persona artifacts. This code chunk only implements one part of that story: Slack data collection. More importantly, it performs a significant capability not reflected in the declared permissions: accessing Slack workspace data using a bot token, including private/public channel history and user enumeration, then saving extracted content locally. Because the declared permissions are empty and the described functionality emphasizes teammate distillation outputs rather than direct Slack harvesting behavior, this is a meaningful description-behavior mismatch.
The code’s actual function is narrow and preparatory: it parses Slack export data for a specified user and outputs formatted message history. While Slack data extraction could be one component of a teammate-distillation workflow, this chunk does not implement the core declared purpose. The declared description emphasizes creating an AI version of a teammate using multi-source data and persona/skill generation, but the code only handles Slack message extraction from an existing export. This is a material mismatch in primary purpose and implemented capabilities.
The declared description promises a higher-level system for distilling a teammate into an AI Skill using Slack/Teams/GitHub data and producing structured outputs like a Work Skill and 5-layer Persona with continuous evolution. The supplied code does not do that. It only parses Teams JSON and Outlook email exports for a specified target and writes extracted message content to a text file. While parsing Teams/Outlook data could be a supporting component of the broader skill, this code chunk’s actual behavior is much narrower and lacks the core advertised functionality. Therefore the description does not accurately represent what this code chunk actually does.
The declared description focuses on knowledge capture and AI teammate creation from external collaboration sources. The actual code does not implement any of that functionality. Instead, it manages local file-based versions for existing teammate skill artifacts (SKILL.md, work.md, persona.md, meta.json), including backup, listing versions, cleanup of old archives, and rollback. This is a materially different primary purpose and introduces an undeclared capability: version archiving/rollback. Therefore the description does not accurately represent this code chunk.
The description promises automatic collection of Slack/Teams/GitHub data but does not foreground that these are privacy-sensitive, potentially confidential sources. Users may invoke the skill without understanding it could access coworkers' communications, code review history, or workplace data, undermining informed consent.
The core workflow is to aggregate a colleague's communications and work artifacts, then transform them into a reusable persona/skill. This is dangerous because it enables large-scale profiling and impersonation using potentially private, employment-related, or confidential materials, with unclear consent and retention boundaries.
The source-import menu explicitly encourages collecting a person's messages, emails, notes, and pasted chat logs as raw inputs. In this context, the skill's purpose is to model a real coworker, which makes the data especially sensitive and heightens the risk of privacy violations, insider information leakage, and reputational harm.
The Slack auto-collect step directs retrieval of a target user's messages and threads into local files, effectively surveilling and retaining a coworker's communications for persona creation. This is highly sensitive workplace data and could expose confidential discussions, personal information, or privileged content at scale.
The skill defines deletion as rm -rf teammates/{slug} using a user-influenced parameter. Without strict slug validation and safe path handling, a crafted value could cause path traversal or deletion of unintended directories, and the use of recursive force deletion makes the impact severe and immediate.
| `/compare {slug1} vs {slug2}` | Read `{baseDir}/prompts/compare.md`, then load both teammates' work.md + persona.md and generate side-by-side comparison |
| `/export-teammate {slug}` | `python3 {baseDir}/tools/export.py --slug {slug} --base-dir ./teammates` — creates portable package |
| `/teammate-rollback {slug} {ver}` | `python3 {baseDir}/tools/version_manager.py --action rollback --slug {slug} --version {ver} --base-dir ./teammates` |
| `/delete-teammate {slug}` | Confirm, then `rm -rf teammates/{slug}` |
---
The trigger list is broad enough to match ordinary conversational feedback like 'actually' or 'more like,' which can cause the correction workflow to activate when the user did not intend to edit persistent skill data. In this skill, unintended activation is especially risky because the handler is designed to convert natural language into durable persona/work rules, allowing accidental or adversarial steering of the generated teammate profile.
The prompt establishes a safety principle of 'Don't speculate,' then later overrides it by mandating inferred content when evidence is absent. This contradiction weakens the model’s reliability guardrails and can cause downstream consumers to treat fabricated details as sourced truth, especially because the output is intended for direct use in generating work.md.
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.
json.dumps(meta, indent=2, ensure_ascii=False), encoding="utf-8"
)
# Generate and write SKILL.md
identity = build_identity(meta)
skill_md = SKILL_MD_TEMPLATE.format(
slug=slug,
The script is explicitly designed to collect a coworker’s Slack messages, thread replies, and activity across public and private channels, then store them locally, but it provides no consent flow, privacy notice, sensitivity filtering, or access-control safeguards. In the context of a skill meant to 'capture a colleague's knowledge before they leave' and create an AI version of them, this substantially raises the risk of unauthorized surveillance, bulk exfiltration of confidential business communications, and downstream misuse of personal or regulated data.
Collecting thread replies expands the capture from a target user’s visible messages into richer conversational context, including sensitive discussions in private channels and replies that may reveal confidential projects, credentials, legal matters, or personal information. Because the skill’s purpose is to distill a person into a reusable AI artifact, this contextual harvesting materially increases the chance of leaking privileged information into local files and later model inputs.
"text": text,
})
# Collect thread replies if this is a thread parent
if msg.get("reply_count", 0) > 0:
try:
thread_response = client.conversations_replies(
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
- **One-shot creation**: Provide name + role + personality in one message → skip 3-question intake
- **Batch corrections**: Fix multiple persona issues in a single pass
- **Auto-apply simple corrections**: No confirmation needed (only on conflicts or Layer 0 changes)
- **Compact merger summaries**: Emoji + one-liner per file, auto-apply on zero conflicts
- **Honest "profile-only" markers**: No fictional examples when source data is skipped
- **Error Recovery**: Graceful script failures, off-script handling, interrupted creation resume
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.
# Per-project (at your git repo root)
mkdir -p .claude/skills
git clone https://github.com/LeoYeAI/teammate-skill .claude/skills/create-teammate
# Or global (all projects)
No suspicious patterns detected.