Back to skill

Security audit

Clawhub Publish Kmwrip1j

Security checks for vulnerabilities and agentic risk

Overview

The skill appears locally focused and not malicious, but it deserves Review because it can collect and persist broad private OpenClaw/workspace history with weak scoping and file-permission safeguards.

Install only if you are comfortable letting it inspect selected OpenClaw/workspace history for personality analysis. Approve the narrowest source categories possible, avoid task/cron sources unless needed, use a private output directory, delete .mbti-reports after use, and avoid --open or follow-up reruns on machines where opening local HTML is undesirable.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mbti_common.py:389
Finding

Sensitive historical data is persisted without explicit private filesystem permissions

Content
View full analysis

Vulnerability Details

File Location: scripts/ingest_all_content.py:254-267; scripts/mbti_common.py:389-411
Vulnerability Type: Sensitive-data persistence with insufficient access controls
Risk Level: Medium

Vulnerable Code

python
records: List[Dict] = []
for source_type in approved_source_types:
    ingestor = INGESTORS.get(source_type)
    if ingestor is None:
        continue
    target_root = workspace_root if source_type.startswith("workspace") else openclaw_home
    records.extend(ingestor(target_root))

write_jsonl(output_dir / "raw_records.jsonl", records)
write_json(
    output_dir / "source_summary.json",
    build_summary(
        records,
        approved_source_types,
        workspace_root,
        openclaw_home,
    ),
)

The shared output helpers create directories and files using process-default permissions:

python
def ensure_dir(path: Path) -> Path:
    path.mkdir(parents=True, exist_ok=True)
    return path


def write_json(path: Path, payload: Any) -> None:
    ensure_dir(path.parent)
    path.write_text(
        json.dumps(payload, ensure_ascii=False, indent=2) + "\n",
        encoding="utf-8",
    )


def write_jsonl(path: Path, rows: Iterable[Dict[str, Any]]) -> None:
    ensure_dir(path.parent)
    with path.open("w", encoding="utf-8") as handle:
        for row in rows:
            handle.write(json.dumps(row, ensure_ascii=False) + "\n")

Technical Analysis

The ingestion stage reads authorized OpenClaw sessions, workspace memory, memory-index content, task summaries, or cron records and duplicates that information into raw_records.jsonl. The generated source_summary.json also includes content previews. Follow-up processing creates additional persistent files containing direct user answers.

These files are sensitive because they can contain private conversation history, personal ...[truncated 2179 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create report directories with owner-only mode 0700.
  2. Create sensitive JSON, JSONL, Markdown, and HTML files atomically with mode 0600, rather than relying on the process umask.
  3. Resolve and validate the output path before writing. Reject symlinks and ensure each output file remains within the intended report directory.
  4. Use temporary files opened with secure exclusive-creation semantics, then atomically replace the final destination.
  5. Add a privacy-preserving mode that streams records through evidence extraction without retaining full raw_records.jsonl.
  6. Minimize source_summary.json by omitting content previews unless the user explicitly requests them.
  7. Document artifact retention and add a secure cleanup command for raw records, evidence excerpts, and follow-up answers.
  8. Warn users when they select a report directory outside the private default location.

T05 · Unauthorized Access and Privilege Escalation

Note
Location
scripts/discover_sources.py:72
Finding

Source discovery reads and persists indexed document paths before authorization

Content
View full analysis

Vulnerability Details

File Location: scripts/discover_sources.py:72-83
Vulnerability Type: Pre-consent metadata access beyond minimum discovery requirements
Risk Level: Low

Vulnerable Code

python
main_sqlite = openclaw_home / "memory" / "main.sqlite"
indexed_rows = load_sqlite_rows(
    main_sqlite,
    "select path from files order by path",
) if main_sqlite.exists() else []
candidates.append(
    {
        "source_type": "openclaw-memory-index",
        "label": SOURCE_DEFINITIONS["openclaw-memory-index"]["label"],
        "note": SOURCE_DEFINITIONS["openclaw-memory-index"]["note"],
        "path_pattern": str(main_sqlite),
        "available": main_sqlite.exists(),
        "item_count": len(indexed_rows),
        "examples": [row["path"] for row in indexed_rows[:5]],
    }
)

Technical Analysis

The Skill’s authorization model states that source discovery occurs before the user authorizes source-content access. Discovery should therefore determine only whether a source category is available and provide enough aggregate information for informed consent.

The implementation opens ~/.openclaw/memory/main.sqlite, enumerates every path in the files table, and includes up to five paths in the generated manifest. File and document paths can reveal project names, client names, topics, usernames, directory structure, or other private metadata even when document contents are not read.

Availability can be determined using Path.exists(), and an aggregate count can be obtained without retrieving or persisting individual paths. Collecting examples is therefore not required for the declared discovery function and violates the intended least-privilege authorization boundary.

The recommended command writes the manifest to the predictable path /tmp/mbti-source-manifest.json. Because the common write helper does not explicitly set owner-only permissions, the collec ...[truncated 1192 chars]

Remediation
View remediation

Remediation Suggestions

  1. During pre-authorization discovery, report only source-category availability and aggregate record counts.
  2. Remove the examples field for memory-index paths until the user explicitly authorizes that source category.
  3. If a count is necessary, use an aggregate query such as select count(*) as count from files instead of enumerating all paths.
  4. Create the manifest using a securely generated, non-predictable temporary filename.
  5. Apply file mode 0600 and ensure the temporary directory is not shared.
  6. Delete the source manifest immediately after authorization and ingestion are complete.
  7. Clearly distinguish consent to inspect source metadata from consent to ingest source contents.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
Findings (25)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose describes a runtime skill for analyzing a user's MBTI from historical conversational and workspace data. The actual code chunk is a developer support script for test setup: it parses CLI arguments, calls fixture-generation helpers, writes stage fixtures to an output directory, and prints JSON. There is no logic for reading user memory/history/notes, no personality inference, and no report generation. This is a materially different primary purpose, so it is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description claims the skill analyzes user personality from authorized OpenClaw memory, session history, and workspace notes. This code chunk does not access those sources or perform substantive MBTI inference over raw conversation/history data. Its main role is downstream presentation: rendering HTML/Markdown reports from already-structured analysis results and evidence pools. It also supports a debug-preview mode that fabricates mock analysis/evidence for layout testing, which is materially different from real evidence-backed inference. Additional behavior includes loading static assets/reference data and optionally opening the output in a browser. Therefore, the supplied code does not accurately represent the declared primary purpose.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/apply_followup_answers.py (reported line 77)May include surrounding context.

python
question = item.get("question")
        if axis in VALID_AXES and question:
            prompts[axis] = question
    return prompts


def followup_record(axis: str, answer: str, output_dir: Path) -> Dict:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/mbti_common.py (reported line 15)May include surrounding context.

python
from typing import Any, Dict, Iterable, Iterator, List

DEFAULT_EXCLUDED_PATTERNS = [
    ".env",
    "credentials/*",
    "identity/*",
    "devices/*",

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README advertises very broad natural-language triggers such as "MBTI," "personality analysis," and "type me," which increases the chance the skill is invoked when a user did not specifically intend to authorize analysis of historical memory, sessions, or workspace notes. In this skill's context, unintended invocation is more sensitive than usual because the analysis may inspect personal conversation history and memory sources, so a mistaken trigger can expose or process more private data than the user expected.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill instructs the agent to read broad categories of local memory/session data, write report artifacts, invoke shell commands, and even open generated HTML, but it declares no explicit tool scope or permission boundaries. In a skill that handles sensitive user history, missing tool restrictions greatly increases the chance of overbroad data access or unsafe execution beyond what the user intended.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill processes sensitive personal history and generates personality inferences, then persists reports and evidence artifacts on disk, yet the user-facing description lacks a clear privacy warning about collection, retention, and quoting of historical content. That omission can lead users to authorize analysis without understanding the sensitivity or storage footprint of the resulting personality dossier.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The maintainer guidance at L057-L058 says 'do not infer MBTI directly from raw history,' but the very next execution instructions tell the agent to invoke analysis from 'authorized memory and session history' and the pipeline's purpose is to derive MBTI from ingested historical records. This is an intent-level contradiction in the skill documentation about whether raw historical content should be directly used for inference.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The skill defaults to writing detailed personality-analysis artifacts, evidence pools, and source summaries into a persistent timestamped directory in the workspace. Persisting derived psychological profiling and excerpts from historical conversations increases the risk of later unauthorized access, accidental inclusion in version control, or reuse beyond the original consent scope.

Content

Scanner excerpt · SKILL.md (reported line 125)May include surrounding context.

Execution Flow

If the user does not provide an output directory, write results to:

text
./.mbti-reports/<timestamp>/

YARA rule 'network_reconnaissance': Network reconnaissance and scanning patterns [hacktools]

Medium
Category
YARA Match
Confidence
65% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · references/famous_people.json (reported line 1039)May include surrounding context.

json
mbti_type": "ISTP",
      "domain": "History",
      "description": "Japanese swordsman and author of The Book of Five Rings.",
      "source": "curated",
      "detail_url": "https://www.stablecharacter.com/personality-database/miyamoto-musashi"
    },
    {
      "name": "Wolverine (Logan)",
      "mbti_type": "ISTP",
      "domain": "Fictional",
      "description": "Marvel superhero known for fierce independence.",
      "source": "curated",
      "detail_url": "https://www.stablecharacter.com/personality-database/wolverine-logan"
    },
    {
      "name": "Vladimir Putin",
      "mbti_type": "ISTP",
      "domain": "Politics",
      "description": "Russian president since 2000.",
      "source": "stablecharacter.com",
      "detail_url": "https://www.stablecharacter.com/personality-database/vladimir-putin"
    }
  ],
  "ISFP": [
    {
      "name": "Lady Gaga",
      "mbti_type": "ISFP",
      "domain": "Music",
      "description": "Pop star and actress known for avant-garde sty

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script enumerates task-run and cron-run artifacts as candidate MBTI evidence sources even though those stores may contain broader operational history unrelated to personality analysis. In this skill context, that expands the data collection surface beyond the stated purpose and increases the risk of over-collection, privacy leakage, and downstream inference from sensitive but irrelevant records.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest written by the script records workspace paths and OpenClaw data locations, which can disclose the existence and structure of sensitive local data stores even if file contents are not copied. In a personality-analysis skill, this matters more because the enumerated locations point to highly personal memory, session, and history artifacts that could later be consumed or exfiltrated by other components.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The AXIS_QUESTIONS strings are hard-coded in Chinese while the rest of the skill output is in English, indicating the skill may impose a specific language on users regardless of preference. The file does not provide any opt-in, locale selection, or documentation that this is a region-specific tool.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill is scoped to MBTI/personality inference from authorized memory, session history, and workspace notes, but this script also ingests task-run and cron-run logs wholesale. Those sources can contain unrelated operational data, commands, summaries, secrets, or sensitive behavioral details, creating unnecessary overcollection beyond the stated purpose and increasing privacy and data-exposure risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script materializes aggregated copies of all ingested content into raw_records.jsonl and source_summary.json, creating a new consolidated dataset that is easier to access, exfiltrate, or misuse than the original scattered sources. Even if the underlying sources are authorized, duplicating them into a central output expands the data footprint and can violate least-privilege and data-minimization expectations for an analysis skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This file hard-codes multiple Chinese-language pattern lists alongside some English phrases for core text classification behavior, which effectively bakes in a language/locale assumption. Because the skill does not provide any opt-in, language selection, or documented justification for restricting behavior around Chinese/English content, it risks violating the policy against forcing a specific language or locale.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This renderer includes capability to launch a browser on the host machine, which is not necessary to generate Markdown/HTML output. In a local CLI this is convenience behavior, but in an agent skill handling user-derived data it expands the skill from passive rendering into host interaction, increasing risk in automated or sandboxed deployments.

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/render_report.py (reported line 1343)May include surrounding context.

python
html_path = html_path.resolve()
    if sys.platform == "darwin":
        subprocess.Popen(["open", str(html_path)])
    elif sys.platform.startswith("linux"):
        subprocess.Popen(["xdg-open", str(html_path)])
    elif sys.platform == "win32":

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/render_report.py (reported line 1345)May include surrounding context.

python
if sys.platform == "darwin":
        subprocess.Popen(["open", str(html_path)])
    elif sys.platform.startswith("linux"):
        subprocess.Popen(["xdg-open", str(html_path)])
    elif sys.platform == "win32":
        subprocess.Popen(["cmd", "/c", "start", "", str(html_path)])
    else:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
73% confidence
Finding

The Windows branch invokes cmd /c start through a command interpreter, which introduces more parsing complexity and a larger attack surface than the macOS/Linux branches. Even though the path is passed as a separate argument, using cmd for file opening is riskier in an agent context because path edge cases and interpreter behavior can produce unintended execution semantics.

Content

Scanner excerpt · scripts/render_report.py (reported line 1347)May include surrounding context.

python
elif sys.platform.startswith("linux"):
        subprocess.Popen(["xdg-open", str(html_path)])
    elif sys.platform == "win32":
        subprocess.Popen(["cmd", "/c", "start", "", str(html_path)])
    else:
        print(f"Cannot auto-open on {sys.platform}; open manually: {html_path}")

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code exposes a natural-language locale policy in the CLI that only permits "auto", "en", or "zh". Under the stated policy, forcing a specific language or locale without user opt-in can be a violation; here, users are constrained to two supported languages rather than being offered open locale choice or documented justification for the limitation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README states that reports are rendered automatically in English or Chinese based on source language mix, which imposes a language/locale choice without stating that the user can choose or opt in. This can violate language/locale policy expectations when users are not offered control over the output language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This instruction imposes a specific output phrasing and section title in English, while the skill also includes Chinese trigger phrases, indicating multilingual use. Without offering a language choice or clarifying that headings should follow the user's language, the skill risks violating language/locale policy expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The section titled "Chinese Context Adjustments" explicitly tailors interpretation guidance to a specific cultural/linguistic context. While it is framed as a general caution, the file does not state that this locale-specific handling is optional, user-selected, or limited to users in that context, which can conflict with a policy requiring language/locale choice or clear justification.

Content

No source excerpt is available for this finding.