Back to skill

Security audit

AI Agent OPSEC — Runtime Classified Data Enforcer

Security checks for vulnerabilities and agentic risk

Overview

This local redaction skill is mostly coherent, but it can persist partially sanitized payload text in audit logs despite promising that logs never contain sensitive text.

Review before installing. The skill does not appear to send data over the network, but its audit log may store snippets of text after limited registry-based redaction. Use it only with a protected audit directory, add the recommended paths to .gitignore, and avoid relying on its current logging as proof that no sensitive content is retained.

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

Warning
Location
src/ClassifiedAccessEnforcer.js:168
Finding

Partially Redacted Input May Leak Sensitive Data into Audit Logs

Content
View full analysis

Vulnerability Details

File Location: src/ClassifiedAccessEnforcer.js:168-173
Vulnerability Type: Plaintext sensitive-data logging
Risk Level: Medium

Vulnerable Code

javascript
if (total > 0) {
  // SECURITY: log uses the already-redacted result for preview — never the original text
  this._log('REDACT', `Removed ${total} classified reference(s) [${context}]`, {
    context,
    count: total,
    redactedPreview: result.substring(0, 80), // safe — already redacted
  });
}

Technical Analysis

The application assumes that result is safe to log because registered classified terms have been replaced. However, redaction only covers exact terms loaded from classified/classified-terms.md. Any sensitive content not present in that registry remains unchanged.

When at least one registered term is detected, the first 80 characters of the partially redacted result are passed to _log() and appended to memory/security/classified-access-audit.jsonl. Consequently, passwords, API tokens, personal information, confidential text, or variants of registered terms may be stored in plaintext if they appear within that preview.

This behavior contradicts the documentation's assertion that the audit log “never contains original sensitive text.” Rotated logs can retain the exposed content beyond the lifetime of the active audit file.

Attack Path

  1. An outbound payload or subagent task contains at least one exact term from the classified-term registry.
  2. The same payload contains another sensitive value that is absent from the registry or does not match its exact redaction pattern.
  3. The caller invokes sanitizeOutbound(), redactTaskBeforeSpawn(), or redactAll().
  4. The registered term is replaced with [REDACTED], while the unregistered sensitive value remains intact.
  5. Because at least one replacement occurred, redactAll() records the first 80 characters of the partially redacted payload.
  6. The residual sensitive value is per ...[truncated 729 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove all payload-derived content from audit records. Log only metadata such as the action, service or context identifier, redaction count, input length, and timestamp.
  2. Replace the vulnerable context with a metadata-only structure:
javascript
this._log('REDACT', `Removed ${total} classified reference(s) [${context}]`, {
  context,
  count: total,
  inputLength: text.length,
  note: 'payload content intentionally omitted'
});
  1. If previews are operationally required, disable them by default and require explicit administrator opt-in. Apply independent credential and secret detection rather than relying solely on the classified-term registry.
  2. Restrict audit directory and file permissions to the service account that owns the process.
  3. Define retention and secure-deletion policies for both active and rotated logs.
  4. Update the documentation so its confidentiality guarantees accurately describe the implemented behavior.
  5. Add automated tests using a payload that contains both a registered term and an unrelated secret, then assert that neither active nor rotated audit files contain the secret.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (4)

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The module documentation explicitly states under 'Side Effects (declared)' that it reads only /classified/classified-terms.md and writes the audit log. Later, getAuditReport() reads from the audit log file, so the documentation actively understates actual file-read behavior rather than merely omitting an implementation detail.

Content

No source excerpt is available for this finding.

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

Scanner excerpt · README.md (reported line 183)May include surrounding context.

md
**USE AT YOUR OWN RISK.**

- The author(s) are NOT liable for any damages, losses, or consequences arising from
  the use or misuse of this software — including but not limited to financial loss,
  data loss, security breaches, business interruption, or any indirect/consequential damages.
- This software does NOT constitute financial, legal, trading, or professional advice.
- Users are solely responsible for evaluating whether this software is suitable for

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The header declares the module's side effects as reading only the classified term list and writing the audit log, framing the skill as a runtime redactor and pre-publish auditor. However, the code also implements getAuditReport(), which reads and parses the audit log contents for retrieval, an additional behavior not reflected in the stated operations.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file header identifies the module as v1.4.0, but the CLI self-test prints 'Testing ClassifiedAccessEnforcer v1.1.0'. This is a direct contradiction in inline documentation/output that can mislead operators about what code version is actually running.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.