Back to skill

Security audit

Tophant Clawvault Mask Project

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed local document-masking skill with no network, credential, persistence, or hidden execution behavior, though users should be careful with custom policies and output paths.

Install only if you are comfortable with a local tool reading the document you name and optionally writing to paths you provide. Review sanitized output before sharing it with an AI model, avoid untrusted custom policy files, and choose output paths carefully because existing writable files may be replaced.

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
mask_project.py:151
Finding

Unbounded Evaluation of Attacker-Controlled Regular Expressions

Content
View full analysis
dict[str, Any]: if not path: return default_policy() policy_path = Path(path).expanduser() data = json.loads(policy_path.read_text(encoding="utf-8")) if not isinstance(data, dict): raise ValueError("Policy must be a JSON object") return data ``` ```python def collect_matches(text: str, policy: dict[str, Any]) -> list[MatchSpan]: matches: list[MatchSpan] = [] for rule in policy.get("rules", []): if not isinstance(rule, dict) or rule.get("type") != "regex": continue label = str(rule.get("label") or "unknown") priority = int(rule.get("priority") or 0) pattern = str(rule.get("pattern") or "") mask_group = rule.get("mask_group") if not pattern: continue compiled = re.compile(pattern, re.MULTILINE) for match in compiled.finditer(text): if mask_group: try: start, end = match.span(str(mask_group)) except IndexError: start, end = match.span() else: start, end = match.span() if start >= 0 and end > start: matches.append(MatchSpan(start=start, end=end, label=label, priority=priority)) return matches ``` ### Technical Analysis The `--policy` option allows a caller to load arbitrary regular-expression patterns from a JSON file. Policy validation verifies high-level fields but does not restrict regex constructs, pattern length, rule count, or execution time. Python's standard `re` engine uses backtracking. A pattern containing nested or ambiguous quantifiers can require exponential processing time when evaluated against a carefu ...[truncated 1594 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
mask_project.py:140
Finding

Unrestricted Output Paths Permit Overwriting Files Accessible to the Process

Content
View full analysis
str: target = Path(path).expanduser() target.parent.mkdir(parents=True, exist_ok=True) target.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") return str(target) ``` ```python output_path = None if args.output: output = Path(args.output).expanduser() if output.resolve(strict=False) == input_path.resolve(strict=False): return json_response( { "success": False, "error": "Output path must be different from the input file path", }, exit_code=1, ) output.parent.mkdir(parents=True, exist_ok=True) output.write_text(sanitized, encoding="utf-8") output_path = str(output) ``` ### Technical Analysis The `--output` and `--save-policy` arguments accept unrestricted filesystem paths. Both write paths create missing parent directories and use `Path.write_text()`, which truncates an existing destination before writing. The `--output` implementation only prevents the resolved output path from being identical to the input path. It does not: - Constrain output to an approved workspace. - Reject existing destinations. - Require explicit overwrite authorization. - Reject symbolic links. - Protect configuration, source, or shell initialization files. - Apply equivalent input-path checks to `--save-policy`. Consequently, a caller who can influence command arguments can replace any file writable by the operating-system account running the skill. This is not a privilege-escalation primitive by itself because operating-system permissions still apply, but it violates safe output ha ...[truncated 1515 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (4)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
- Writes only optional sanitized output files or optional saved policy JSON files.
- Does not request network access.
- Does not start or require the ClawVault proxy or dashboard.
- Does not access credentials.
- Does not output original matched values.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill returns the full sanitized document content inline in its JSON response. In agent settings, returning large portions of document content to the caller or orchestration layer can still expose sensitive business data beyond the minimum necessary scope, especially because regex masking is incomplete and misses are explicitly possible via the warning path. The skill’s purpose is to protect company-project documents, so echoing document contents in the response materially increases data exposure risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill explicitly describes reading a user-specified file and optionally writing sanitized output or policy files, but it does not declare any tool scope such as permissions or allowed-tools. That omission weakens least-privilege controls and makes the skill's file access behavior less constrained and less auditable, which is a real security design issue even though the documented purpose appears benign.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The custom policy loader reads any path supplied by the user and parses it as JSON, allowing the skill to access arbitrary local files unrelated to the target document. In an agent environment, this broad file-read capability can be abused to probe or exfiltrate local data from locations outside the intended working set, even if parsing failures limit what is returned directly.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.