T02 · Agent Memory Poisoning
Warning
- Location
- scripts/dongwo.py:620
- Finding
- Forgeable profile markers allow persistent agent memory poisoning<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dongwo.py:620-628, 661` **Vulnerability Type**: Unauthenticated persistent memory injection **Risk Level**: Medium ### Vulnerable Code ```python def profile_lines() -> list[str]: if not PROFILE.exists(): return [] result: list[str] = [] for raw in PROFILE.read_text(encoding="utf-8").splitlines(): if raw.lstrip().startswith("- ") and "<!-- human:" in raw: cleaned = re.sub(r"\s*<!--\s*human:[^>]+-->\s*$", "", raw).strip() if cleaned and cleaned not in result: result.append(cleaned) return result[:24] ``` The resulting entries are subsequently inserted into generated agent context without content validation: ```python lines.extend(profile_lines() or ["- 暂无。"]) ``` ### Technical Analysis The implementation treats any list item containing an inline `<!-- human:... -->` marker as a user-confirmed profile entry. This marker is neither authenticated nor tied to an explicit approval record. Any process or person able to create or modify the configured `myprofile.md` can forge it. Unlike prompt inbox entries, profile entries do not pass through the sensitive-data checks, recognized-preference allowlist, or pending-review workflow. Their text is copied verbatim into `current-context.md`, which lifecycle hooks later return as additional agent context. This violates the intended trust boundary between untrusted project-controlled data and user-confirmed memory. Although the generated context contains a warning that stored content is not a command, that natural-language warning is only a defense-in-depth measure and cannot securely neutralize adversarial prompt text. The issue best matches agent memory poisoning because forged content persists in a local profile and can influence subsequent agent sessions whenever Dongwo context is loaded. ### Attack Path 1. An attacker obtains the ability to supply or modify files in a project w ...[truncated 1796 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Do not use an inline comment as proof of confirmation.** Treat all existing `myprofile.md` content as untrusted unless it is approved through a separate, explicit workflow. 2. **Store approvals separately.** Maintain a local approval record containing a cryptographic hash of each approved entry, its approval timestamp, and an identifier for the approval action. Only inject entries whose current content matches an approved hash. 3. **Use a strict preference schema.** Restrict confirmed profile data to low-risk fields such as output language, verbosity, and formatting preferences. Do not inject arbitrary free-form profile lines. 4. **Apply the same safety pipeline used for inbox data.** Reject or quarantine entries containing: - instruction-priority changes; - requests to ignore safeguards; - credential or secret references; - tool calls or executable commands; - file, network, deletion, payment, or privilege-change instructions. 5. **Require explicit approval for pre-existing profiles.** On first setup, display discovered profile entries and require the user to confirm them before lifecycle hooks can inject them. 6. **Separate data from instructions.** Serialize approved preferences into a constrained machine-readable structure and render only canonical statements generated by the engine, rather than copying source text verbatim. 7. **Add regression tests.** Verify that a forged `<!-- human:... -->` marker cannot cause arbitrary text to appear in `current-context.md`, and test mixed benign-preference and malicious-instruction payloads. ]]>
