Back to skill

Security audit

A2a E2ee Encryption

Security checks for vulnerabilities and agentic risk

Overview

This skill is not deceptive and does not persist, exfiltrate, or modify local data, but its security-critical cryptographic implementation has correctness gaps users should review before relying on it.

Install only if you understand this is a small crypto utility rather than a reviewed protocol implementation. It does not show malicious behavior, but users should not rely on its secure-envelope or HMAC APIs for high-value agent commands, financial actions, or irreversible workflows without fixing and testing the identified cryptographic edge cases.

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

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:74
Finding
Incorrect RSA-OAEP plaintext-size calculation causes encryption failures## Vulnerability Details **File Location**: `index.js:74-92` **Vulnerability Type**: Incorrect cryptographic boundary validation **Risk Level**: Medium ```javascript const maxDirectSize = (RSA_KEY_SIZE / 8) - 42; // PKCS#1 v1.5 padding overhead if (messageBuffer.length <= maxDirectSize) { // Direct RSA encryption for small messages const encrypted = crypto.publicEncrypt( { key: recipientPublicKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, oaepHash: HASH_ALGORITHM }, messageBuffer ); return { type: 'direct', encrypted: encrypted.toString('base64'), algorithm: 'RSA-OAEP' }; } ``` ### Technical Analysis The implementation calculates the maximum direct RSA plaintext size by subtracting 42 bytes, which is the OAEP overhead associated with SHA-1. However, encryption is configured to use SHA-256. The RSA-OAEP maximum plaintext size is: `modulusBytes - (2 × hashLength) - 2` For a 2048-bit RSA key and SHA-256, this is `256 - 64 - 2 = 190` bytes. The implementation incorrectly allows up to 214 bytes. Consequently, messages between 191 and 214 bytes are routed to direct RSA encryption and rejected by the underlying cryptographic implementation. The calculation also relies on the fixed `RSA_KEY_SIZE` constant rather than inspecting the supplied public key. This produces additional incorrect decisions when callers use keys of a different modulus size. ### Attack Path 1. An attacker supplies or causes the application to encrypt a message between 191 and 214 bytes. 2. The size check incorrectly selects the direct RSA encryption branch. 3. `crypto.publicEncrypt` attempts RSA-OAEP encryption with SHA-256. 4. OpenSSL rejects the oversized OAEP plaintext and throws an exception. 5. If the caller does not isolate the exception, the current operation fails and may terminate a request handler or service process. ### Impact Assessment ...[truncated 362 chars]
Remediation
## Remediation Suggestions - Derive the modulus length from `recipientPublicKey` rather than using the fixed `RSA_KEY_SIZE` constant. - Calculate the OAEP boundary using the configured SHA-256 digest length: `modulusBytes - (2 * 32) - 2`. - Prefer hybrid RSA-OAEP and AES-GCM encryption for all message sizes, eliminating the fragile direct-encryption branch. - Validate inputs and convert cryptographic exceptions into controlled application errors. - Add boundary tests for 189, 190, 191, 213, and 214-byte messages and for every supported RSA key size.

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:217
Finding
Malformed HMAC values can trigger an exception during verification## Vulnerability Details **File Location**: `index.js:217-220` **Vulnerability Type**: Improper authentication-input validation **Risk Level**: Medium ```javascript function verifyHMAC(message, hmac, key) { const computed = computeHMAC(message, key); return crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(computed)); } ``` ### Technical Analysis `crypto.timingSafeEqual` requires both buffers to have exactly the same byte length. The computed SHA-256 HMAC is represented as a 64-character hexadecimal string, but the untrusted `hmac` argument is neither decoded as hexadecimal nor validated for its encoding and expected length. Supplying a string of any different length causes `timingSafeEqual` to throw a `RangeError` instead of returning `false`. The function therefore fails open at the availability boundary: malformed authentication data is handled as an exceptional condition rather than a normal verification failure. The comparison also operates on UTF-8 representations of hexadecimal strings rather than directly comparing the underlying 32-byte MAC values. ### Attack Path 1. An attacker submits a message with a malformed, truncated, or oversized HMAC value. 2. `verifyHMAC` computes the expected 64-character hexadecimal HMAC. 3. `Buffer.from(hmac)` and `Buffer.from(computed)` produce buffers with different lengths. 4. `crypto.timingSafeEqual` throws a `RangeError`. 5. Without appropriate exception handling, the request fails and may disrupt the enclosing service. ### Impact Assessment An unauthenticated attacker who controls an HMAC input can cause deterministic verification exceptions and application-level denial of service. No privilege escalation, secret disclosure, or authentication bypass was demonstrated. The scope depends on whether the host application catches exceptions around `verifyHMAC`.
Remediation
## Remediation Suggestions - Require the supplied HMAC to be a valid 64-character hexadecimal value. - Decode both values using `Buffer.from(value, 'hex')` and verify that both decoded buffers are exactly 32 bytes. - Return `false` for invalid encoding or length before invoking `timingSafeEqual`. - Catch unexpected cryptographic errors at the service boundary so malformed authentication data cannot terminate request processing. - Add tests for empty, truncated, oversized, non-hexadecimal, and correctly sized invalid HMAC values.

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:283
Finding
Secure envelopes allow replay and do not authenticate timestamp or version metadata## Vulnerability Details **File Location**: `index.js:283-323` **Vulnerability Type**: Missing replay protection and incomplete signature coverage **Risk Level**: Medium ```javascript function createSecureEnvelope(message, recipientPublicKey, senderPrivateKey) { const encrypted = encrypt(message, recipientPublicKey); const signature = sign(JSON.stringify(encrypted), senderPrivateKey); return { version: '1.0', encrypted, signature, timestamp: Date.now() }; } function openSecureEnvelope(envelope, recipientPrivateKey, senderPublicKey) { // Verify signature const signatureValid = verify( JSON.stringify(envelope.encrypted), envelope.signature, senderPublicKey ); if (!signatureValid) { throw new Error('Invalid signature - message may have been tampered'); } // Decrypt message const message = decrypt(envelope.encrypted, recipientPrivateKey); return { message, signatureValid, timestamp: envelope.timestamp }; } ``` ### Technical Analysis The signature covers only the serialized `encrypted` object. Security-relevant envelope metadata, including `version` and `timestamp`, is excluded from the signature and can therefore be modified without invalidating it. In addition, `openSecureEnvelope` does not enforce a freshness window, validate timestamp semantics, require a unique message identifier, maintain a replay cache, or track sequence numbers. A previously captured valid envelope remains cryptographically valid indefinitely. Because the returned timestamp is taken directly from the unsigned envelope, an attacker can replace the timestamp on an old message and make it appear current while preserving a valid signature. ### Attack Path 1. An attacker captures a legitimate signed and encrypted envelope in transit or from a message queue or log. 2. The attacker optionally changes the unsigned `timestamp` ...[truncated 979 chars]
Remediation
## Remediation Suggestions - Sign a canonical representation of every security-relevant field, including the protocol version, timestamp, ciphertext, sender identity, recipient identity, algorithm identifiers, and a unique message ID or nonce. - Avoid relying on ordinary `JSON.stringify` as a protocol-level canonicalization scheme; use a defined canonical JSON format or a deterministic binary encoding. - Enforce a narrowly defined timestamp freshness window and reject timestamps that are too old or unreasonably far in the future. - Maintain a replay cache of consumed message IDs for at least the full acceptance window, or use strictly validated per-sender sequence numbers. - Bind sender and recipient identities into the signed data to prevent cross-context message reuse. - Add tests confirming that metadata modification and duplicate submission are rejected.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Vague Triggers

Medium
Confidence
91% confidence
Finding
The listed trigger scenarios such as 'Need to encrypt messages between agents' and 'Implementing secure communication protocols' are high-level and open-ended, with no explicit constraints or negative examples. This makes the skill's invocation scope ambiguous and increases the chance of unintended activation for general discussions about security or messaging.

Description-Behavior Mismatch

Low
Confidence
81% confidence
Finding
The manifest describes key generation, message encryption/decryption, and key management for secure A2A communication. This file additionally exposes generic digital signature and HMAC helpers as first-class APIs, which are broader cryptographic capabilities than the declared encryption-focused scope, even though they are related to secure messaging.

Description-Behavior Mismatch

Low
Confidence
84% confidence
Finding
The manifest centers on E2EE for agent-to-agent communication, with key generation and encryption/decryption utilities. The additional shared-secret generation plus symmetric encrypt/decrypt functions introduce a different communication model that is not inherently end-to-end in the asymmetric A2A sense described by the manifest.

Static analysis

No suspicious patterns detected.