T09 · Insecure Skill Coding Practices
- Location
SKILL.md:82- Finding
Unredacted Agent Output Is Sent to a Third-Party Service Before PII Filtering
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 82–105, 125–126, 182–188, 202–212, and 226–229
Vulnerability Type: Sensitive-data exposure through insecure processing order
Risk Level: MediumVulnerable Code Snippets
The documented configuration connects the agent to an external MCP service:
json { "mcpServers": { "dcl-trust-oracle": { "url": "https://mcp.fronesislabs.com/mcp" } } }The complete agent output is supplied to the remote evaluation tool:
python result = dcl_evaluate_jailbreak( response=agent_output, agent_id="my-agent-01", ) if result["verdict"] == "NO_COMMIT": block_or_regenerate(result["reason"]) else: log_audit(result["tx_hash"])The skill only promises that raw responses are not persisted:
text Only `input_hash` (a hash of the evaluated text) is stored — the raw response itself is never persisted server-side.The documented pipeline places PII redaction after the external policy evaluation:
text DCL Policy Enforcer ← this skill (live paid check, or free checklist) │ COMMIT ▼ DCL Sentinel Trace ← PII redactionThe same document recognizes that evaluated output can contain sensitive values:
text ### PII Surface Patterns - [ ] Output contains email addresses - [ ] Output contains phone numbers - [ ] Output contains national ID or SSN-shaped strings - [ ] Output contains bank card PANs or IBANs - [ ] Output contains crypto wallet addresses - [ ] Output contains IP addressesTechnical Analysis
The live evaluation accepts
agent_outputas itsresponseargument. Consequently, the external service must receive and process the plaintext output before it can compute a verdict and input hash. The statement that raw text is not persisted does not mean that raw text is not transmitted, temporarily buffered, logged by ...[truncated 2369 chars]- Remediation
View remediation
Remediation Suggestions
-
Redact before transmission: Move PII, credential, and secret detection ahead of every live Policy Enforcer call. Only sanitized content should be supplied as
response. -
Default to local processing: Use the free instruction-only checklist by default. Require an explicit opt-in before sending text to the external MCP endpoint.
-
Obtain informed consent: Clearly disclose that the complete response, rather than only its hash, must be transmitted for evaluation. Obtain consent before handling personal, medical, financial, or otherwise confidential content.
-
Minimize submitted data: Send only the smallest text segment required for the selected policy check. Remove metadata and context that are not necessary for evaluation.
-
Block prohibited data classes: Refuse live evaluation when the response contains credentials, national identifiers, payment-card data, medical records, or other restricted information unless an approved data-processing agreement and lawful basis exist.
-
Define verifiable processing controls: Document transport security, transient buffering, server and proxy logging, retention periods, subprocessors, geographic processing locations, incident handling, and deletion guarantees.
-
Secure failure behavior: If redaction fails or the content cannot be classified safely, fail closed and use the local checklist rather than forwarding the original response.
-
Control wallet spending: Require per-call authorization or enforce strict budgets, rate limits, and maximum transaction values for x402 payments.
-
Update the documented pipeline: Place PII redaction and secret scanning before all external checks:
text LLM output → PII and secret redaction → explicit transmission approval → DCL Policy Enforcer → delivery
-
