Back to skill

Security audit

Memory Health Probe

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real memory diagnostics tool, but it under-discloses sensitive telemetry storage and local HTTP reporting behavior.

Review before installing. Use dry-run mode unless you explicitly want detailed memory probe results written locally and sent to a local Langfuse service. Treat the hardcoded Langfuse keys, raw query telemetry, source URIs, and gateway-log access as sensitive, and prefer a version with clear permission scoping, redaction, HTTPS or safer local transport, and opt-in persistence/export.

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
scripts/memory_probe.py:33
Finding

Hardcoded Langfuse Secret Transmitted Using Basic Authentication over Plaintext HTTP

Content
View full analysis
str | None: """Log probe result to Langfuse as a trace. Returns trace ID or None.""" import urllib.request import base64 creds = base64.b64encode(f"{LANGFUSE_PK}:{LANGFUSE_SK}".encode()).decode() headers = { "Authorization": f"Basic {creds}", "Content-Type": "application/json", } trace_id = f"memory-probe-{TODAY}" payload = { "id": trace_id, "name": "memory_probe_daily", "timestamp": datetime.now(timezone.utc).isoformat(), "metadata": { "probe_date": TODAY, "backend": "qmd", "qmd_version": "1.0.7", }, "input": {"query_count": len(QUERIES), "domains": list({q["domain"] for q in QUERIES})}, "output": probe_result, "tags": ["memory", "qmd", "telemetry"], } try: req = urllib.request.Request( f"{LANGFUSE_URL}/api/public/traces", data=json.dumps(payload).encode(), headers=headers, method="POST", ) with urllib.request.urlopen(req, timeout=10) as resp: return trace_id except Exception as e: print(f" ⚠ Langfuse log failed: {e}") return None ``` ```python def log_scores_to_langfuse(trace_id: str, scores: list[dict]): """Log per-metric scores to Langfuse.""" import urllib.request import base64 creds = base64.b64encode(f"{LANGFUSE_PK}:{LANGFUSE_SK}".encode()).decode() headers = { "Authorization": f"B ...[truncated 3415 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (7)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script transmits probe output to Langfuse over plain HTTP using Basic authentication, and the payload includes rich retrieval metadata. Even on localhost, unencrypted transport and static credentials are poor practice; if the service is rebound, proxied, containerized, or exposed through port forwarding, sensitive telemetry and credentials could be intercepted or misrouted.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill metadata does not declare an explicit tool scope or permissions model, yet the skill description and usage indicate capabilities that can read/write files, invoke shell commands, and potentially perform networked logging via Langfuse/OpenClaw components. This creates an authorization gap: operators cannot easily constrain what the skill is allowed to do, and the mismatch between 'outbound: false' and 'Langfuse integration' further increases uncertainty about actual runtime behavior.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/memory_probe.py (reported line 81)May include surrounding context.

python
def run_qmd_status() -> dict:
    """Parse `qmd status` output into structured metrics."""
    try:
        out = subprocess.run(
            [str(QMD_BIN), "status"],
            capture_output=True, text=True, timeout=30
        ).stdout

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/memory_probe.py (reported line 104)May include surrounding context.

python
def run_bm25_search(query: str) -> dict:
    """Run `qmd search` and return hit/score/collection."""
    try:
        result = subprocess.run(
            [str(QMD_BIN), "search", query, "-n", "1"],
            capture_output=True, text=True, timeout=15
        )

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The probe reads broad gateway logs and derives counts from them, which expands collection beyond the stated retrieval-quality diagnostics scope. In a memory/telemetry context, gateway logs may contain unrelated operational or user-derived information, so this creates unnecessary data access and increases the chance of overcollection or downstream disclosure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script saves and exports detailed query telemetry, including exact canonical queries, top-hit collections, and source URIs, which exceeds a simple health/coverage summary. Because several queries reference sensitive personal or credential-related topics, exporting raw retrieval metadata can reveal the existence, location, and relevance of sensitive memory content to anyone with access to local snapshots or Langfuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The probe writes a JSON snapshot containing detailed query results to local disk by default, without clearly warning the user that sensitive retrieval metadata will be persisted. Local persistence increases exposure to other local users, backups, support bundles, or later accidental sharing, especially because the dataset includes source URIs and sensitive query themes.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.