Back to skill

Security audit

HH OpenClaw Agent

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed hh.ru application workflow helper with local packet and report scripts, with some report-safety caveats but no evidence of hidden or destructive behavior.

Use this only when you are comfortable letting an agent assist a logged-in hh.ru application workflow. Review and approve the packet before any live submit action, handle authentication challenges yourself, avoid recording cookies or tokens, and treat reports generated from untrusted or externally edited manifests as potentially misleading until sanitized.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/check_hh_submission_bundle.py:20
Finding

Artifact path validation permits repository-root escape

Content
View full analysis
bool: return path_text.startswith("/") or path_text.startswith("~") or ":\\" in path_text or path_text.startswith("file://") ``` ```python for field in ARTIFACT_FIELDS: artifact_path = str(artifacts.get(field, "")).strip() if not artifact_path: continue if is_absolute_or_private(artifact_path): add_finding(findings, "error", "absolute-artifact-path", f"{field} uses an absolute or private path.", step_id) continue candidate = repo_root / artifact_path if not candidate.exists(): add_finding(findings, "warning", "missing-artifact", f"{field} path does not exist under repo root: {artifact_path}", step_id) ``` ### Technical Analysis The validator rejects several obvious absolute-path forms but does not canonicalize the resulting artifact path or verify that it remains within `repo_root`. A path such as `../../private/file.txt` is not considered absolute or private by `is_absolute_or_private()`. When joined with `repo_root`, it can resolve to a file outside the intended bundle directory. The same issue applies to symlinks inside the repository that resolve to external locations. Windows drive-qualified paths using forward slashes, such as `C:/private/file.txt`, are also not detected by the check for `":\\"`. The existence test therefore does not establish the property claimed by its warning message: that the artifact exists “under repo root.” It only establishes that the constructed path exists after operating-system path resolution. ### Attack Path 1. An attacker or untrusted bundle producer supplies a manifest containing an artifact path such as: ```json { "artifacts": { "screenshot": "../../ ...[truncated 1316 chars]
Remediation
View remediation
Path: raw = Path(path_text) if raw.is_absolute() or raw.drive: raise ValueError("Artifact path must be relative") root = repo_root.resolve() candidate = (root / raw).resolve(strict=False) try: candidate.relative_to(root) except ValueError as exc: raise ValueError("Artifact path escapes repository root") from exc return candidate ``` Additional hardening should include: 1. Reject paths containing parent traversal components such as `..`, even when canonical containment would otherwise catch them. 2. Use `Path.is_absolute()` and inspect `Path.drive` instead of relying on string-prefix checks. 3. Resolve symlinks and reject candidates whose resolved targets are outside `repo_root`. 4. Require artifacts to be regular files rather than directories or special files: ```python if not candidate.is_file(): # Emit an error. ``` 5. Treat containment violations as errors, not warnings. 6. Add regression tests for POSIX traversal, Windows path forms, mixed separators, URL-like paths, and escaping symlinks. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/render_hh_submission_report.py:81
Finding

Untrusted manifest content is rendered as active Markdown

Content
View full analysis
Remediation
View remediation
str: text = str(value) text = text.replace("\\", "\\\\") for char in ("`", "*", "_", "{", "}", "[", "]", "(", ")", "#", "+", "-", ".", "!", "|", "<", ">"): text = text.replace(char, "\\" + char) return text.replace("\r", " ").replace("\n", " ") ``` Further hardening should include: 1. Apply escaping to all packet, review, summary, step, issue-key, and artifact-label values. 2. Sanitize multiline fields with a maintained Markdown sanitization library instead of relying solely on custom replacement logic. 3. Disable or strip raw HTML. 4. Allow only explicitly approved URL schemes and hosts for any rendered links or images. 5. Do not permit remote images in reports intended for offline audit or sharing. 6. Render sensitive cover-letter content in a fenced or escaped plain-text block when `--include-sensitive` is enabled. 7. Add tests containing links, images, raw HTML, backticks, newlines, and formatting delimiters in every user-controlled field. ]]>
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description presents a public hh.ru application skill whose main purpose is browser-driven application execution and producing a reviewed submission bundle. The code shown does not implement that agent behavior. Instead, it only reads a manifest JSON, validates fields and step/artifact metadata, checks for missing or unsafe artifact paths, enforces that submitted steps require approved review status, and emits a validation report. While this is related to an auditable submission bundle, it is only a supporting validation utility and not the declared primary skill behavior. Therefore the supplied code chunk materially differs from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broader hh.ru application agent for browser-executed application automation and reviewed submission bundles. The supplied code chunk does not implement that agent behavior. It merely loads a JSON manifest, redacts sensitive fields by default, formats packet/review/step data, and writes a markdown report. This is related to hh.ru submission bundles, but its primary purpose is report rendering, not logged-in browser execution or application automation. Therefore the code chunk materially underdelivers relative to the declared purpose and represents a mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill describes behavior that involves file access, generated artifacts, and browser/network-oriented workflow, but it does not declare any explicit tool scope or allowed-tools boundaries. This is dangerous because operators and enforcement systems cannot clearly constrain what capabilities the skill is expected to use, increasing the risk of overbroad execution or privilege misuse if the implementation is expanded or interpreted permissively.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.