Back to skill

Security audit

lazarillo

Security checks for vulnerabilities and agentic risk

Overview

The skill appears purpose-built rather than malicious, but it needs Review because it can send WhatsApp messages for a user and some safety promises are not technically enforced.

Install only in a tightly controlled OpenClaw environment where outbound WhatsApp sending is restricted to the wrapper script, the single allowed inbound chat is enforced outside the model, and users understand that voice notes may carry secrets because they are not content-scanned before sending.

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

Error
Location
scripts/enviar.py:239
Finding

Sensitive-content controls are bypassed for outbound audio messages

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/revisar-privacidad.sh:7
Finding

Privacy publication guard does not detect contact files by filename

Content
View full analysis
/dev/null \ | grep -vE "\+525550000000|\+525550000001|\+52XXXXXXXXXX" || true) if [[ -n "$hits" ]]; then echo "FALLA: $desc"; echo "$hits" | head -5; MAL=1 else echo " ok $desc"; fi } revisa "ningun telefono real" '\+[0-9]{11,15}' revisa "ningun correo" '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' revisa "ningun id de telegram" '\b1[0-9]{9}\b' revisa "ninguna libreta real" '(^|/)contactos\.md$' revisa "ninguna llave de sistema" '(sk-[A-Za-z0-9_-]{16,}|AIza[A-Za-z0-9_-]{20,})' ``` ### Technical Analysis The `revisa` function uses recursive `grep`, which applies each regular expression to file contents. The expression intended to detect a contact book, `(^|/)contactos\.md$`, is a filename/path pattern rather than a content pattern. Because the script does not pass file paths to that expression, an actual file named `contactos.md` will ordinarily not match. The script may therefore report `PRIVACIDAD: limpio` even when a private contact book exists in the publication tree. The other checks provide only partial mitigation. A contact book containing names, aliases, addresses, notes, nonstandard phone formats, or other personal information can avoid the phone, email, Telegram-ID, and key patterns. ### Attack Path 1. A real contact book is accidentally copied into the public repository under the filename `contactos.md`. 2. Its contents do not contain values matching the script’s limited phone, email, Telegram-ID, or API-key expressions. 3. The privacy script invokes recursive `grep` with the filename-oriented pattern. 4. `grep` searches file contents rather than repos ...[truncated 857 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Hay coincidencia parcial importante: el código sí respalda la parte de 'manda sus mensajes y sus notas de voz con confirmación hablada obligatoria'. Sin embargo, la descripción general del skill es más amplia e incluye leer documentos/correo y redactar textos, funcionalidades ausentes en este fragmento. Además, el código introduce comportamientos materiales no declarados relacionados con seguridad y operación: resuelve destinatarios desde una libreta local, exige coincidencia de 4 dígitos del teléfono, maneja modos como solo-lectura/retenido, filtra contenido sensible en mensajes de texto, limita rutas de audio y escribe un registro de auditoría. Eso hace que la descripción no represente con precisión suficiente lo que este código realmente hace.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is for an end-user accessibility assistant focused on messaging, reading content, and drafting text for someone with low vision. The supplied code does none of those things. Instead, it implements a privacy/publication check over files in the project directory, searching for real-looking personal data and system keys, then signaling whether the content is safe to publish. This is a materially different primary purpose and introduces undeclared capabilities unrelated to the stated assistive functions.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README makes a strong safety claim that nothing is sent without mandatory spoken confirmation, but later admits that key anti-send behaviors are only model instructions and are not technically enforced. In this skill’s context, the user cannot reliably verify on-screen actions, so a mismatch between claimed guarantees and actual enforcement materially increases the risk of unauthorized or mistaken communications.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The README presents a single closed-fail sending bottleneck as a core safeguard, but later discloses that the agent’s shell access allows bypassing that bottleneck entirely. For an assistive skill acting on behalf of a low-vision user, this undermines the primary trust boundary and means a compromised or misaligned agent could send messages outside the documented safety path.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill directs the agent to use shell execution (python3 scripts/enviar.py), read local files such as memory/contactos.md, and rely on logging/operational files, but it does not declare any explicit tool permissions or scope boundaries. In an agent environment, undeclared capabilities weaken least-privilege controls and make it easier for the skill to access or modify resources beyond what reviewers and runtime policy expect.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The description and operating instructions force a single language/locale experience for the skill user and operator. Under the policy, language constraints should either be optional or clearly documented as a justified locale-specific constraint; this file does not state such an opt-in or limitation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module docstring, CLI examples, and all user-facing prompts are written exclusively in Spanish, and the confirmation logic only accepts Spanish trigger phrases such as "manda" and "envia". This imposes a language constraint on users without any documented opt-in or explicit justification for a locale-specific deployment.

Content

No source excerpt is available for this finding.

Tainted flow: 'REG' from os.environ.get (line 16, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
90% confidence
Finding

The log path REG is derived from LAZARILLO_BASE, which comes from an environment variable, and is later opened for append without constraining it to a trusted directory. If an attacker can influence the service environment, they can redirect writes to unintended files, potentially causing log forgery, file clobbering, or writes through symlinks in a security-sensitive workflow that treats logging as a precondition for sending.

Content

Scanner excerpt · scripts/enviar.py (reported line 183)May include surrounding context.

python
os.makedirs(os.path.dirname(REG), exist_ok=True)
    try:
        import fcntl
        with open(REG, "a", encoding="utf-8") as fh:
            fcntl.flock(fh, fcntl.LOCK_EX)
            fh.write(json.dumps(evento, ensure_ascii=False) + "\n")
            fh.flush()

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

python
if a.dry_run:
        cmd.append("--dry-run")
    try:
        r = subprocess.run(cmd, capture_output=True, text=True, timeout=TIMEOUT_ENVIO)
        rc, salida = r.returncode, (r.stdout + r.stderr).strip()
    except subprocess.TimeoutExpired:
        rc, salida = 124, f"se colgo mas de {TIMEOUT_ENVIO} segundos"

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file uses Spanish exclusively for user-facing documentation, beginning with the heading and continuing throughout the release notes. Under the policy rule, forcing a specific language without opt-in or justification can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The README includes a locale-specific statement that the skill is in use "en español de México." For a language/locale policy check, this can read as a fixed locale expectation without documenting user choice, opt-in, or a clear region-specific justification in the skill description.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

Line L25 states "Respuestas siempre en audio," which imposes a fixed communication mode for all interactions. Under the policy rule, hard-coded language/locale-style communication constraints should be flagged when the user is not offered an explicit choice or opt-in.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.