Back to skill

Security audit

meeting-autopilot

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but it sends sensitive meeting content and API credentials to configurable external endpoints and stores meeting-derived history by default.

Review before installing in any environment that handles confidential meetings. Use only approved LLM endpoints, avoid custom http endpoints, consider disabling history with --no-history, and treat generated emails/tickets as drafts requiring human review.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (3)

T01 · Skill Instruction Hijacking

Error
Location
scripts/generate-outputs.sh:251
Finding

Forced Promotional Content in Every Generated Report

Content
View full analysis
$BRAND_FOOTER | v$VERSION | Items stored locally for cross-meeting tracking." echo "" echo "💡 *Tip: Install via \`meeting-autopilot\` for one-command meeting analysis.*" ``` Relevant instructions in `SKILL.md:103-115`: ```markdown ### Step 4: Present the Report The script outputs a complete Markdown report to stdout. Present it directly — the formatting is designed to look great in Slack, email, or any Markdown renderer. ### Step 5: Offer Next Steps After presenting the report, offer: 1. "Want me to refine any of the email drafts?" 2. "Should I adjust any action item assignments?" 3. "Want to save this report to a file?" 4. "I can also process another meeting — transcripts from different meetings build up a tracking history." ``` ### Technical Analysis The report generator unconditionally appends vendor branding and an installation solicitation to every generated report. The Skill instructions then tell the Agent to present the report directly, causing this unrelated promotional material to propagate into the Agent's user-visible response. There is no command-line option or configuration setting to suppress the promotional footer. Consequently, the final output is not solely determined by the user's meeting-processing request. ### Attack Path 1. A user asks the Agent to process a meeting transcript. 2. The Agent follows `SKILL.md` and invokes `scripts/meeting-autopilot.sh`. 3. `scripts/generate-outputs.sh` generates the report. 4. The script unconditionally appends the `Powered by Anvil AI` attribution and installation solicitation. 5. The Skill instructions dir ...[truncated 529 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/common.sh:103
Finding

Custom Plaintext API Endpoints Can Receive Sensitive Transcripts and API Credentials

Content
View full analysis
/dev/null) # Extract text content printf '%s' "$response" | jq -r '.content[0].text // empty' 2>/dev/null return elif [ -n "${OPENAI_API_KEY:-}" ]; then # OpenAI API local openai_base openai_base="${OPENAI_API_URL:-https://api.openai.com}" validate_http_url "$openai_base" "OPENAI_API_URL" local request_body request_body=$(jq -n \ --arg model "${OPENAI_MODEL:-gpt-4o}" \ --arg system "$system_prompt" \ --arg user "$u ...[truncated 2914 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/extract-items.sh:179
Finding

Untrusted Transcript Instructions Can Manipulate LLM-Generated Reports

Content
View full analysis
/dev/null) OPERATIONAL_OUTPUTS=$(printf '%s' "Meeting: $MEETING_TITLE Participants: $SPEAKERS EXTRACTED ITEMS: $ITEMS_SUMMARY" | call_llm "$OUTPUT_PROMPT") if [ -z "$OPERATIONAL_OUTPUTS" ]; then log_warn "LLM returned empty for operational outputs. Generating report without email/ticket drafts." OPERATIONAL_OUTPUTS="" fi ``` The resulting model output is subsequently written directly into the Markdown report: ```bash if [ -n "$OPERATIONAL_OUTPUTS" ]; then echo "---" echo "" echo "$OPERATIONAL_OUTPUTS" echo "" fi ``` ### Technical Analysis The transcript is untrusted user-controlled data, but it is embedded directly in the LLM user message without a robust instruction-data boundary. The system prompt requests extraction but does not explicitly state that instructions, policy text, or role directives found inside the transcript must be treated solely as meeting content. The first model's output is parsed as JSON, but the individual fields are not validated against a strict schema, bounded by length, or checked for instruction-like payloads. Those fields are then transformed into `ITEMS_SUMMARY` and supplied to a second LLM. This ...[truncated 1845 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (22)

Instruction Override

High
Category
Prompt Injection
Confidence
90% confidence
Finding

This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Content

Scanner excerpt · SECURITY.md (reported line 50)May include surrounding context.

md
| Abuse Case | Risk | Mitigation |
|------------|------|------------|
| Malicious transcript content triggers LLM injection | **Medium** | LLM prompts are structured with clear system/user separation. User content is clearly delineated as "TRANSCRIPT:" block. Cannot override system instructions in standard API usage. |
| Transcript with shell metacharacters in speaker names | **Low** | Speaker names extracted via Python JSON parsing, never executed in shell context. All values go through `jq --arg` for JSON output. |
| Path traversal via filename argument | **Low** | File existence checked via `[ -f "$path" ]`. History filenames are sanitized (alphanumeric + hyphens only). |
| Large transcript causes memory exhaustion | **Low** | Bounded by LLM context window. Extremely large files may cause Python to use significant memory but will not crash the system. |

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · SECURITY.md (reported line 55)May include surrounding context.

md
| Path traversal via filename argument | **Low** | File existence checked via `[ -f "$path" ]`. History filenames are sanitized (alphanumeric + hyphens only). |
| Large transcript causes memory exhaustion | **Low** | Bounded by LLM context window. Extremely large files may cause Python to use significant memory but will not crash the system. |
| History directory symlink attack | **Low** | `mkdir -p` follows symlinks but creates the directory. History files are JSON only, never executed. |
| Sensitive meeting content in history files | **Medium** | History stores extracted items, not full transcripts. Users can delete history at `~/.meeting-autopilot/history/`. `--no-history` flag skips storage entirely. |

## Network Behavior

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The code is broadly aligned with part of the description: it performs LLM-based extraction of operational meeting artifacts, especially action items and decisions, and uses prompt-driven multi-pass logic (though combined into one API call). However, the declared purpose claims broader outputs and input handling than this chunk actually implements. This script only accepts parsed JSONL produced by another parser, not raw VTT/SRT/plain text directly. It also does not create follow-up email drafts or ticket drafts; instead it extracts/classifies items into categories like decision, action_item, open_question, parking_lot, and key_point and returns summary counts. So the description overstates the capabilities of the supplied code chunk in materially important ways.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents the skill as an operator that transforms meeting transcripts into higher-level operational artifacts. The actual code chunk is only a transcript parser/normalizer for VTT, SRT, and plain text, producing JSONL transcript segments. While input format support matches part of the description, the primary purpose is materially different: preprocessing/parsing rather than extracting or generating operational outputs. There is no evidence of summarization avoidance, no LLM usage, and no generation of action items, decisions, follow-up emails, or ticket drafts.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/extract-items.sh` — LLM extraction + classification

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/generate-outputs.sh` — Operational output generation + report formatting

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file describes that extracted meeting items are stored locally at ~/.meeting-autopilot/history/ as JSON, which affects user data handling and privacy. Under the markdown-file criteria for missing user warnings, the description should explicitly warn users about retention of potentially sensitive meeting content.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

The file explicitly states that meeting transcripts are sent to an external LLM API endpoint. Because transcripts may contain sensitive business, personnel, or financial information, this is a real data-exposure risk if the skill is used on confidential meetings. The risk is contextual and disclosed, but the transmission itself is still security-relevant.

Content

Scanner excerpt · SECURITY.md (reported line 60)May include surrounding context.

md
## Network Behavior

This skill makes API calls ONLY to the configured LLM provider:
- **Anthropic:** `https://api.anthropic.com/v1/messages` (or custom `ANTHROPIC_API_URL`)
- **OpenAI:** `https://api.openai.com/v1/chat/completions` (or custom `OPENAI_API_URL`)

No other network calls are made. No telemetry. No phone-home.

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

The OpenAI endpoint is another explicit external transmission path for potentially sensitive meeting data. Even though the behavior is documented and appears intentional, sending confidential transcript content to third-party APIs creates a genuine confidentiality and compliance risk.

Content

Scanner excerpt · SECURITY.md (reported line 61)May include surrounding context.

md
This skill makes API calls ONLY to the configured LLM provider:
- **Anthropic:** `https://api.anthropic.com/v1/messages` (or custom `ANTHROPIC_API_URL`)
- **OpenAI:** `https://api.openai.com/v1/chat/completions` (or custom `OPENAI_API_URL`)

No other network calls are made. No telemetry. No phone-home.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation phrases are broad enough to trigger on ordinary meeting-related requests, which can cause the agent to invoke a high-privilege workflow unexpectedly. In this skill, that matters because activation can lead to shell execution, network calls to external LLM APIs, and persistent storage of transcript-derived data, increasing the chance of unintended processing of sensitive business content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill states that items are automatically saved to ~/.meeting-autopilot/history/ but does not prominently warn users up front that meeting content may be retained persistently. Meeting transcripts often contain confidential business discussions, names, decisions, and action items, so silent retention increases privacy and data-governance risk, especially on shared machines or managed enterprise endpoints.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

This curl call sends transcript-derived content and meeting metadata to the Anthropic API, which is an external network boundary crossing. In the context of a meeting automation skill, that means potentially confidential transcript material leaves the local environment and may be disclosed to a third-party service if used on sensitive meetings.

Content

Scanner excerpt · scripts/extract-items.sh (reported line 96)May include surrounding context.

sh
}')

    local response
    response=$(printf '%s' "$request_body" | curl -sS \
      "${anthropic_base%/}/v1/messages" \
      -H "Content-Type: application/json" \
      -H "x-api-key: ${ANTHROPIC_API_KEY}" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script transmits full meeting transcript content to third-party LLM providers without any runtime warning, consent check, or built-in redaction step. Because transcripts can contain sensitive business, HR, legal, or personal data, this creates a real data exposure risk, especially in enterprise environments where operators may not realize external processing occurs.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

This OpenAI API request similarly transmits transcript content to an external service, creating the same confidentiality and compliance risk as the Anthropic path. The danger is heightened by the skill's purpose: meeting transcripts often contain internal operational decisions, customer information, and sensitive follow-up actions.

Content

Scanner excerpt · scripts/extract-items.sh (reported line 128)May include surrounding context.

sh
}')

    local response
    response=$(printf '%s' "$request_body" | curl -sS \
      "${openai_base%/}/v1/chat/completions" \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer ${OPENAI_API_KEY}" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This curl call transmits user-supplied meeting content to the Anthropic API, which is an external network boundary. In the context of a meeting-automation skill, the payload can include sensitive transcript-derived operational details, so sending it off-host creates confidentiality and compliance risk if users are unaware or data handling is not approved.

Content

Scanner excerpt · scripts/generate-outputs.sh (reported line 80)May include surrounding context.

sh
}')

    local response
    response=$(printf '%s' "$request_body" | curl -sS \
      "${anthropic_base%/}/v1/messages" \
      -H "Content-Type: application/json" \
      -H "x-api-key: ${ANTHROPIC_API_KEY}" \

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This curl call sends the assembled prompt and meeting-derived content to the OpenAI API, exposing potentially sensitive internal information to an external service. The risk is heightened because the script is designed to process operational meeting outputs, which may contain action items, decisions, owners, and other business-sensitive content.

Content

Scanner excerpt · scripts/generate-outputs.sh (reported line 109)May include surrounding context.

sh
}')

    local response
    response=$(printf '%s' "$request_body" | curl -sS \
      "${openai_base%/}/v1/chat/completions" \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer ${OPENAI_API_KEY}" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script sends meeting title, participant names, and extracted meeting items to an external LLM service without any explicit consent prompt, warning, or local-only mode at the point of use. Because meeting transcripts often contain confidential business discussions, personal data, or internal decisions, this can cause unintended data disclosure to third-party providers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script sends parsed meeting transcript content to an external LLM service, but this entrypoint does not provide an explicit privacy warning or consent checkpoint before doing so. Meeting transcripts commonly contain sensitive business, HR, customer, or legal information, so silent transmission to third-party APIs can create confidentiality, compliance, and data handling risks even if the behavior is intended.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script persists cross-meeting history to disk by default, including extracted items and summaries derived from transcripts, without an explicit retention warning or affirmative opt-in. Because meeting outputs may contain sensitive operational decisions, personnel actions, credentials, or customer details, default persistence increases the chance of unintended disclosure through local access, backups, or later reuse.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The prompt mandates a specific communication style and email formatting in English, including fixed section labels such as "Subject," "To," and "next steps," with no user opt-in or locale choice. This can violate language or locale policy when users or meeting content require another language.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file header states 'Pass 1' extracts raw items and 'Pass 2' classifies each item, implying separate stages. However, the actual logic combines the extraction and classification prompts and sends them in one call, which contradicts the documented behavior rather than merely omitting detail.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.