Back to skill

Security audit

vemem — visual entity memory

Security checks for vulnerabilities and agentic risk

Overview

The skill is transparent about its visual-memory purpose, but it handles biometric data and its examples can place persisted free-form facts into privileged model context, so it belongs in Review before installation.

Install only if you are comfortable storing biometric identifiers locally and can control which images are processed. Use a dedicated virtual environment and test `VEMEM_HOME`, pin the `vemem` package version, avoid the automatic OpenClaw sidecar unless you want every image attachment processed, and treat recalled facts as untrusted data rather than system-level instructions.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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 (2)

T02 · Agent Memory Poisoning

Error
Location
references/examples.md:35
Finding

Persisted Untrusted Facts Are Promoted into Privileged LLM System Context

Content
View full analysis

Vulnerability Details

File Location: references/examples.md:35-56
Additional Locations: references/examples.md:76-101, references/examples.md:118-145, SKILL.md:213, references/mcp-tools.md:180
Vulnerability Type: Persistent prompt injection through untrusted memory
Risk Level: High

Vulnerable Code:

python
if candidates:
    scene = ollama.chat(
        model="qwen2-vl:7b",
        messages=[{
            "role": "user",
            "content": "Describe what this person is doing in one sentence.",
            "images": [image_bytes],
        }],
    )["message"]["content"]
    vem.remember(candidates[0].entity.id, scene, source=Source.VLM)

# Read path — assemble context for the chat LLM
context_lines = []
for c in candidates:
    facts = "; ".join(f.content for f in c.facts)
    context_lines.append(f"- {c.entity.name} (conf {c.confidence:.2f}): {facts}")
context = "People visible:\n" + "\n".join(context_lines) if context_lines else "No known faces."

reply = ollama.chat(
    model="llama3.1",
    messages=[
        {"role": "system", "content": f"Visual context:\n{context}"},
        {"role": "user", "content": "What's happening? Who's here?"},
    ],
)

Equivalent vulnerable flows appear in the OpenAI and Anthropic examples:

python
vem.remember(candidates[0].entity.id, scene, source=Source.VLM)

context = ""
for c in vem.identify(image_bytes, k=3):
    context += f"- {c.entity.name}: {', '.join(f.content for f in c.facts)}\n"

return (client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": f"Visual context:\n{context}"},
        {"role": "user", "content": user_msg},
    ],
).choices[0].message.content or "")

Technical Analysis

VLM-generated descriptions and other free-form facts are persisted using vem.remember() without content validation, trust labeling, instr ...[truncated 2556 chars]

Remediation
View remediation

Remediation Suggestions

  1. Never interpolate retrieved facts or VLM output directly into a system message.
  2. Place recalled facts in a lower-privilege message or a dedicated structured-data channel.
  3. Explicitly instruct the downstream model that recalled content is untrusted data and must not be interpreted as commands.
  4. Use structured serialization with fixed fields rather than free-form prompt concatenation.
  5. Escape or reject content containing prompt delimiters, role markers, tool-call syntax, or instruction-like phrases.
  6. Preserve provenance and trust metadata for every fact, including whether it came from a user, VLM, LLM, or import.
  7. Require user confirmation before persisting VLM-generated descriptions as durable facts.
  8. Quarantine low-trust facts and exclude them from agent decision-making or tool authorization.
  9. Apply content-length limits and normalization before storage and retrieval.
  10. Ensure tool authorization is enforced outside the LLM so poisoned prompts cannot independently authorize sensitive actions.
  11. Add tests using images and stored facts containing adversarial instructions to verify that they remain inert data.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:93
Finding

Unpinned Third-Party Package Installation and Execution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:93-100
Additional Locations: references/examples.md:271, references/examples.md:297-298, references/troubleshooting.md:12-16, references/troubleshooting.md:57
Vulnerability Type: Unconstrained third-party dependency installation
Risk Level: Medium

Vulnerable Code:

markdown
### Quick check — is vemem available?

Run `python -c "import vemem; print(vemem.__version__)"`. If that fails, install:

```bash
pip install vemem
# or with uv:
uv pip install vemem
text

The integration example also immediately executes an installed entry point:

```bash
pip install vemem
vemem-openclaw-sidecar &   # HTTP sidecar on localhost

Troubleshooting guidance additionally recommends reinstalling the latest available package:

bash
pip install --force-reinstall vemem

Technical Analysis

The primary installation instructions resolve and install the current package release and its transitive dependencies without a mandatory version pin, hash verification, or lockfile. The documentation later recommends pinning versions in production, but the principal copy-and-paste setup, integration, and troubleshooting commands remain unconstrained.

Installing and running the package is necessary for the Skill's declared visual-memory functionality. However, resolving an unspecified release at installation time creates a supply-chain trust gap: the code that executes can differ from the version reviewed when the Skill documentation was published.

The project under audit contains only Markdown instructions. The actual vemem package, MCP server, OpenClaw sidecar, dependencies, and model download logic are external and therefore were not available for implementation-level verification.

Attack Path

  1. A user or agent follows pip install vemem or an equivalent unpinned command.
  2. The package manager resolves the latest packag ...[truncated 1480 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace every installation example with an explicitly pinned, reviewed release, such as vemem==0.1.0.
  2. Provide cryptographic hashes and use hash-enforcing installation, such as pip install --require-hashes -r requirements.txt.
  3. Supply a lockfile that pins all transitive dependencies.
  4. Keep the pinned version consistent across setup, examples, and troubleshooting instructions.
  5. Do not recommend --force-reinstall without a pinned version and verified artifacts.
  6. Install the package in a dedicated virtual environment with access limited to the required image and storage paths.
  7. Run the MCP server and sidecar under a restricted account or sandbox with minimal filesystem and network permissions.
  8. Require explicit review before upgrading the package or model dependencies.
  9. Document expected package hashes, entry points, opened sockets, and filesystem access for each reviewed release.
  10. Consider disabling outbound network access after verified model weights and dependencies have been provisioned.
  11. Verify downloaded model artifacts using publisher-provided checksums or signatures.
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/troubleshooting.md (reported line 73)May include surrounding context.

md
Three possible causes, ordered by likelihood:

1. **Different encoder between write and read.** Encoder version is part of identity-of-evidence. If the write side used `insightface/arcface@0.7.3` and the read side uses `insightface/arcface@0.8.0`, the gallery is empty for the new encoder. Check `encoder.id` on both sides. Fix: pin the insightface version or accept that an encoder bump means rebuilding the gallery (v0 limitation; re-embed path is a v0.1 item).

2. **Confidence threshold too strict.** Default is 0.5. For face verification on real images, 0.35 is often a better floor. Retry with `min_confidence=0.2` to see raw scores:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This markdown file includes a last-resort command that moves ~/.vemem aside and tells the user to start fresh, which can effectively discard the active store from normal use and require relabeling. Although it notes some consequences, it does not clearly warn up front that this is a destructive recovery action affecting persisted user data and should be used with caution.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.