Back to skill

Security audit

Backend Developer

Security checks for vulnerabilities and agentic risk

Overview

This email agent is mostly coherent, but it handles user-provided email instructions in a privileged prompt while enabling email sending, which deserves review before installation.

Review how EmailTool validates recipients, sender identity, body, attachments, and approval decisions before installing. Treat generated email fields as untrusted, and prefer a fixed system prompt with user instructions placed in a lower-privilege, clearly delimited message.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T01 · Skill Instruction Hijacking

Warning
Location
email.agent.ts:30
Finding
User-Controlled Instructions Are Elevated to a System Message## Vulnerability Details **File Location**: `email.agent.ts`, lines 30–39 **Vulnerability Type**: Prompt injection through privileged instruction placement **Risk Level**: Medium ```typescript async sendEmail(dto: SendEmailDto) { const { email, name, subject = '', body = '', instructions = '' } = dto; const result = await this.agent.invoke({ messages: [ { role: "system", content: message.EMAIL_PROMPT(instructions), }, { role: "user", content: message.EMAIL_USER_MESSAGE(email, name, subject, body), }, ], }); ``` ### Technical Analysis The caller-controlled `dto.instructions` value is passed to `message.EMAIL_PROMPT` and the resulting content is assigned the privileged `system` role. Consequently, untrusted instructions may be interpreted with greater authority than the email data supplied in the `user` message. An attacker could submit instructions that attempt to override the intended email-composition rules, alter recipients or message content, conceal relevant information from the approver, or induce unintended `EmailTool` calls. The implementation of `message.EMAIL_PROMPT` was outside the supplied audit scope, so any internal escaping or delimitation could not be verified. The configured human-in-the-loop middleware requires an approve, edit, or reject decision for `EmailTool`, which reduces the likelihood of automatic delivery. It does not eliminate the underlying prompt-injection condition because manipulated output or tool arguments may still be presented to an approving user. ### Attack Path 1. An attacker or untrusted caller provides a crafted value in `dto.instructions`. 2. `sendEmail` passes that value to `message.EMAIL_PROMPT`. 3. The generated prompt is assigned the `system` role. 4. The model interprets the attacker-controlled text as privileged instructions and may compose altered content or request an unintended `Em ...[truncated 851 chars]
Remediation
## Remediation Suggestions - Use a fixed, application-controlled system prompt. Place caller-provided composition preferences in a clearly delimited user-role message rather than interpolating them into system-role content. - Treat model-generated tool arguments as untrusted. Validate and authorize the recipient, subject, body, attachments, and other delivery options inside `EmailTool`. - Bind the permitted recipient and other security-sensitive fields to validated application data instead of allowing the model to redefine them. - Apply schema validation, length limits, and control-character filtering to every `SendEmailDto` field. - Display a structured approval view showing the final recipient, subject, body, attachments, and sender identity. Highlight differences between requested and model-generated values. - Verify with integration tests that `humanInTheLoopMiddleware` reliably intercepts the exact registered tool name and that rejection prevents all delivery side effects. - Ensure authorization and recipient policy checks remain mandatory even when a human approves the request.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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 (1)

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- **edit** - Modify the email before sending
- **reject** - Cancel the email operation

The `readEmailTool` is excluded from interruption (`false`), allowing read operations to proceed without approval.

## Parameters
Confidence
75% confidence
Finding
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.

Static analysis

No suspicious patterns detected.