T02 · Agent Memory Poisoning
- Location
SKILL.md:115- Finding
Untrusted Evernote Content Can Poison Persistent Agent Memory
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is purpose-aligned, but it reads broad private Evernote content and writes long-term AI memory with too little review, scoping, and persistence control.
Install only if you are comfortable letting the agent read sensitive notebooks and save derived personal facts into long-term memory. Prefer a limited notebook set, review proposed USER.md and memory changes before writing, avoid scheduled sync until disable/removal steps are clear, and do not store Evernote tokens in shell profiles or command history.
SKILL.md:115Untrusted Evernote Content Can Poison Persistent Agent Memory
references/setup.md:25Third-Party Python Dependencies Are Installed Without Version or Integrity Pinning
SKILL.md:89Evernote Developer Tokens May Be Exposed Through Command Arguments and Plaintext Shell Configuration
The supplied code does partially align with the Evernote-to-Markdown portion of the description, since it converts ENEX note exports into a local Markdown file. However, the broader declared purpose materially overstates the behavior. There is no logic for note analysis, no reading or writing of USER.md or any Memory files, and no synchronization workflow with Evernote notebooks beyond local conversion of a provided ENEX file. The actual primary purpose of this code chunk is ENEX-to-Markdown conversion, not user-model updating or AI memory management.
The code’s actual behavior is limited to invoking evernote_backup to sync Evernote data into a backup database and export notebooks as .enex files. The declared description includes additional substantive capabilities: syncing to local Markdown, analyzing notes, and updating USER.md and Memory files. None of those behaviors appear in this code chunk. While the Evernote sync portion partially aligns, the output format and downstream processing are materially different from the declared purpose, so this is a description-behavior mismatch.
The skill instructs the agent to ingest private notes and derive structured identity, habits, relationships, goals, and preferences, then persist that data into reusable memory/profile files. This creates a high-risk concentration of sensitive personal information that can outlive the original session, expand access within the agent ecosystem, and amplify harm if those files are exposed, misused, or later referenced inappropriately.
The README prominently advertises full notebook syncing, diary analysis, and automatic updates to persistent profile/memory files, but it does not give a clear upfront warning that highly sensitive personal content will be ingested into the AI analysis context and transformed into durable artifacts. In a skill whose core purpose is to extract identity, habits, relationships, goals, and emotions from private notes, insufficient consent and disclosure materially increases the risk of privacy harm, oversharing, and long-term retention of sensitive data.
Documenting scheduled automatic syncing without a clear warning means users may enable recurring ingestion of newly added sensitive notes and continuous updates to persistent memory files without appreciating the ongoing privacy implications. This is especially risky because diaries and work notes can change over time, causing fresh sensitive information to be repeatedly analyzed and retained.
The skill instructs the agent to run shell commands and write files, but it does not declare an explicit tool scope such as allowed tools or permissions. That weakens containment and reviewability, making it easier for a broadly-capable agent runtime to perform higher-impact actions than users may expect.
The skill directs the agent to modify USER.md, create multiple memory files, update an index, and later set up recurring jobs, but it does not require an explicit confirmation immediately before those state-changing actions. This can cause silent persistence of sensitive personal data and unattended future execution, which is especially risky given the highly private source material being processed.
The skill includes instructions to register a recurring job that reruns syncing and analysis, creating session persistence beyond the user's immediate interaction. Persistent automation increases the blast radius of mistakes, can repeatedly process newly added private notes without fresh review, and may continue running after the user forgets it was enabled.
1. Default interval: `24h`
2. Parse the interval (e.g., `6h`, `12h`, `24h`, `7d`)
3. Use the agent's cron/scheduler to register a recurring job that runs `/notes-know-you sync`
4. Confirm to the user: "Scheduled notes-know-you to run every {interval}. Next run: {datetime}."
---
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Linux:
sudo apt install pandoc # Debian/Ubuntu
sudo dnf install pandoc # Fedora
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Linux:
sudo apt install pandoc # Debian/Ubuntu
sudo dnf install pandoc # Fedora
The setup guide instructs users to place a long-lived Evernote developer token in shell profiles or persistent environment configuration without warning that such secrets can be exposed through dotfile backups, shell history, shared profiles, process inspection, or accidental publication. Because this skill handles personal notes and identity-related memory files, compromise of the token could expose sensitive note contents and enable unauthorized synchronization access.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def html_to_markdown(html_content: str) -> str:
result = subprocess.run(
["pandoc", "--from=html", "--to=gfm"],
input=html_content,
capture_output=True,
The module docstring says the script accepts [--backend china|evernote] [--token TOKEN], implying backend selection and explicit token handling are part of the script's interface. In reality, the argument parser only defines db_path, enex_output_dir, and --skip-sync, so the documented intent actively contradicts the implemented behavior.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def run(cmd: list[str], label: str) -> subprocess.CompletedProcess:
print(f"[notes-know-you] {label}...")
result = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8")
if result.stdout:
print(result.stdout, end="")
if result.stderr:
Line L017 presents the primary descriptive instruction in Chinese, which can impose a language expectation without user opt-in. The file does not state that the user may choose language or that the Chinese wording is region-specific and intentional.