Back to skill

Security audit

calendarizador-urgencias-formula100k

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent urgency-calendar generator, but it needs review because it relies on an undeclared external bridge skill and can create Excel files from web results without neutralizing hidden spreadsheet formulas.

Install only if you are comfortable with Tavily/Composio web searches using the product brief and with the skill reading narrowly relevant local business context from cerebro/. Treat generated Excel files as untrusted until the spreadsheet-writing code escapes formula-like values, and review any referenced f100k-puente bridge skill before relying on this package.

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/build_xlsx.py:83
Finding
Untrusted Tavily Results Can Cause Spreadsheet Formula Injection## Vulnerability Details **File Location**: `scripts/build_xlsx.py:83-91, 333-347` **Vulnerability Type**: Spreadsheet formula injection **Risk Level**: Medium ### Complete Code Snippet ```python def fill_row(ws, row: int, values: list, fill: PatternFill, height: int = None) -> None: for j, v in enumerate(values, start=1): cell = ws.cell(row=row, column=j, value=v) cell.alignment = WRAP cell.border = BORDER cell.fill = fill if height: ws.row_dimensions[row].height = height ``` The vulnerable helper is used to write Tavily source metadata directly into workbook cells: ```python fuentes = data.get("fuentes_tavily") or [] if fuentes: ws7 = wb.create_sheet("Fuentes Tavily") style_title(ws7, 1, 2, "FUENTES CONSULTADAS (TAVILY)") for j, h in enumerate(["Título", "URL"]): ws7.cell(row=2, column=j + 1, value=h) style_header(ws7, 2, 2) for i, f in enumerate(fuentes): fill = ALT_FILL if i % 2 == 0 else WHITE_FILL fill_row(ws7, 3 + i, [f.get("titulo", ""), f.get("url", "")], fill, 28) autosize(ws7, [50, 80]) ws7.freeze_panes = "A3" out_path.parent.mkdir(parents=True, exist_ok=True) wb.save(out_path) ``` ### Technical Analysis `SKILL.md:215-248` directs the agent to perform Tavily web searches and retain consulted source titles and URLs. Those values originate from independently controlled web pages and therefore cross an external-content trust boundary. `build_xlsx.py` reads these values from `fuentes_tavily` and passes them unchanged to `openpyxl` through `Worksheet.cell(..., value=v)`. Values beginning with spreadsheet formula prefixes—most importantly `=`—are not neutralized or forced to the string data type. Consequently, a malicious page title such as a formula expression can be stored as an active formula rather than displayed as literal text. The generic `fill_row` function also writes othe ...[truncated 1955 chars]
Remediation
## Remediation Suggestions Treat every value obtained from Tavily or other external content as untrusted before writing it to a workbook. 1. Introduce a centralized literal-cell sanitizer and apply it in `fill_row`: ```python FORMULA_PREFIXES = ("=", "+", "-", "@") def spreadsheet_literal(value): if isinstance(value, str) and value.startswith(FORMULA_PREFIXES): return "'" + value return value def fill_row(ws, row: int, values: list, fill: PatternFill, height: int = None) -> None: for j, value in enumerate(values, start=1): cell = ws.cell( row=row, column=j, value=spreadsheet_literal(value), ) cell.alignment = WRAP cell.border = BORDER cell.fill = fill if height: ws.row_dimensions[row].height = height ``` 2. Apply the same protection to every direct cell assignment containing brief, generated, or Tavily-derived data—not only to the source-title column. 3. Alternatively, explicitly force untrusted cells to the string data type after assignment, while verifying through tests that `openpyxl` serializes them as literal strings. 4. Add regression tests covering values beginning with `=`, `+`, `-`, and `@`, including formulas that reference external resources. 5. Keep legitimate hyperlinks separate from displayed text. Validate URL schemes against a narrow allowlist such as `https` before assigning hyperlink targets.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (11)

Ae1

High
Category
analysis-evasion
Content
1. `references/anatomia-urgencia.md` — Motor biológico, 5 gatillos de decisión, anatomía F100K, reglas de oro
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
1. `references/anatomia-urgencia.md` — Motor biológico, 5 gatillos de decisión, anatomía F100K, reglas de oro
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
1. `references/anatomia-urgencia.md` — Motor biológico, 5 gatillos de decisión, anatomía F100K, reglas de oro
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
2. `references/pool-semanal-templates.md` — Templates de razones semanales por TIPO de activo del producto
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
2. `references/pool-semanal-templates.md` — Templates de razones semanales por TIPO de activo del producto
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
La skill usa capacidades de lectura de archivos de forma explícita (`references/...`, `cerebro/`, detección de carpetas) pero no declara un alcance de herramientas/permisos. Esa omisión reduce la visibilidad y el control del entorno sobre qué recursos puede tocar la skill, lo que puede llevar a acceso a archivos no previsto o demasiado amplio si el runtime concede capacidades implícitas.

Vague Triggers

Medium
Confidence
97% confidence
Finding
El disparador `cualquier variación que combine urgencia/escasez con planear cuándo activarla` es demasiado amplio y puede hacer que la skill se active fuera de contexto. Eso incrementa el riesgo de ejecución no intencional con acceso web/archivos, o de que intercepte solicitudes que deberían ir a otra skill menos privilegiada o más específica.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
La descripción inicial menciona investigación web real y entrega de archivos, pero no advierte claramente que la skill hará llamadas a servicios externos ni que escribirá en disco. Esa falta de transparencia debilita el consentimiento informado del usuario y puede exponer datos del brief a terceros o generar archivos locales sin expectativa clara.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The file defines a default estacionality calendar specifically for LATAM/ES without requiring confirmation of the user's geography or locale. In a planning skill, this can cause the agent to generate culturally or commercially incorrect urgency calendars for users in other markets, leading to misleading recommendations and degraded output quality.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
Todo el contenido instruccional y las plantillas del skill están redactados en español y no incluyen ninguna indicación de que el idioma de salida deba adaptarse a la preferencia del usuario ni una justificación de que la skill sea exclusiva para un contexto hispanohablante. Según la política indicada, forzar un idioma sin opt-in del usuario constituye una violación de locale/language policy.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
This code file contains natural-language instructions and console-visible text exclusively in Spanish, beginning in the module docstring and continuing through argument help text and worksheet labels. Under the language/locale policy, forcing a specific language without user opt-in or a clearly documented regional justification is a policy concern.

Static analysis

No suspicious patterns detected.