Back to skill

Security audit

Andara Meeting Minutes

Security checks for vulnerabilities and agentic risk

Overview

This meeting-minutes skill has a clear purpose, but it automatically writes potentially sensitive meeting content to PostgreSQL using unsafe SQL templates and limited user control.

Review this skill before installing. It should only be used with a dedicated least-privilege PostgreSQL account, parameterized or safely escaped inserts, and an explicit confirmation step before saving meeting content. Avoid using it for confidential meetings until storage, retention, and review controls are clear.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:14
Finding

SQL Injection Through Unsafe Interpolation of Meeting Data

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 14–27
Vulnerability Type: SQL injection caused by direct interpolation of user-controlled data
Risk Level: High

Vulnerable Code

bash
psql "$DATABASE_URL" -c "
INSERT INTO team_meetings (title, summary, attendees, meeting_date, created_at)
VALUES ('TOPIC', 'SUMMARY', ARRAY['ATTENDEE1','ATTENDEE2'], NOW(), NOW())
RETURNING id;"
bash
psql "$DATABASE_URL" -c "
INSERT INTO meeting_action_items (meeting_id, assignee, description, due_date, status, created_at)
VALUES (MEETING_ID, 'ASSIGNEE', 'TASK DESCRIPTION', 'DUE_DATE', 'pending', NOW());"

Technical Analysis

The skill instructs the agent to extract the meeting topic, summary, attendees, action-item assignees, descriptions, and due dates from user-supplied text and place them directly into SQL statements passed to psql -c.

No parameter binding, type enforcement, or SQL-literal escaping is specified. A malicious value containing a single quote and additional SQL syntax could terminate its intended literal and alter the command. The same weakness affects several fields, including TOPIC, SUMMARY, attendees, ASSIGNEE, TASK DESCRIPTION, and DUE_DATE. Improper handling of MEETING_ID could also permit SQL manipulation because it is inserted as an unquoted expression.

Although the SQL is enclosed in a shell string, the primary confirmed issue is SQL injection into PostgreSQL rather than shell command injection. The achievable result depends on the privileges of the database role referenced by DATABASE_URL.

Attack Path

  1. An attacker submits meeting content containing a crafted value in a parsed field, such as the title, summary, attendee name, assignee, task description, or due date.
  2. The agent extracts the malicious content and substitutes it into one of the documented SQL templates.
  3. The agent invokes psql "$DATABASE_URL" -c with the resulting SQL text.
  4. PostgreSQL interprets the injected syntax ...[truncated 1102 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace generated SQL strings with a trusted PostgreSQL client that supports prepared statements and bound parameters.
  • Bind every user-derived value, including titles, summaries, attendee names, assignees, descriptions, and due dates.
  • Treat meeting_id as a typed integer obtained directly from the preceding insert result; do not accept or interpolate it from user input.
  • Parse and validate due dates against an explicit date format before database insertion.
  • Pass attendees as a properly typed PostgreSQL array parameter rather than constructing an array literal manually.
  • If psql is unavoidable, use PostgreSQL-safe variable mechanisms with explicit literal handling instead of concatenating content into SQL. Prepared statements in an application client remain preferable.
  • Execute the skill under a dedicated least-privilege database role restricted to the required INSERT and necessary SELECT operations on team_meetings and meeting_action_items.
  • Deny schema modification, role administration, extension installation, and access to unrelated tables.
  • Add adversarial tests covering quotes, semicolons, SQL comments, Unicode edge cases, malformed dates, and oversized input.
  • Use transactions so that meeting and action-item creation succeeds or fails atomically, reducing inconsistent records when validation or insertion fails.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
Findings (3)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill stores meeting summaries, attendees, decisions, and action items in PostgreSQL but does not warn users that their input will be persisted. Meeting notes often contain sensitive internal or personal information, so silent storage creates privacy, consent, and data-governance risk, especially if activation is accidental.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger conditions are broad enough that ordinary conversation containing phrases like 'Meeting Notes' or 'save meeting' could activate the skill unintentionally. Because the skill performs persistent database writes, accidental activation could store sensitive meeting content without clear user intent or confirmation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The instruction "Reply in German" imposes a specific language on all responses with no opt-in or alternative language option. This is a natural-language policy concern because it restricts output locale regardless of user preference or context.

Content

No source excerpt is available for this finding.