Back to skill

Security audit

Guiro

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but it can publish user-provided data to a public no-login link without an explicit pre-publish consent or sensitivity check.

Install only if users understand that payload contents are sent to Guiro and the resulting URL is public to anyone who has it until expiration. Do not use it for secrets, private customer data, confidential business records, or sensitive financial details unless the data is deliberately redacted and the user explicitly approves publication. Prefer GUIRO_API_KEY from the environment, avoid --api-key arguments, and rotate any key that may have appeared in process logs.

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/create-guiro.sh:55
Finding
Arbitrary User Data Is Published Through an Unauthenticated Public Share Link Without Disclosure Safeguards<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:18-22, 64-72, 165-177`; `scripts/create-guiro.sh:55-57, 76-82` **Vulnerability Type**: Uncontrolled disclosure of potentially sensitive user data to a third-party public-sharing service **Risk Level**: High ### Complete Code Snippets From `SKILL.md`: ```markdown **Guiro** (<https://guiro.io>) is an ephemeral Presentation Layer as a Service. You give it a structured JSON bundle describing a layout of visual components, and it returns a short-lived, publicly accessible share link (e.g. `https://guiro.io/s/{slug}`). The rendered page is a polished, read-only visual — a dashboard, report, chart, calendar, or status page. No login or account is needed to view it. Use this skill whenever you produce structured results — metrics, tables, timelines, financial data, event schedules, progress tracking — and want to turn them into a shareable visual artifact the user can open in a browser, send to a colleague, or print to PDF. ``` ```markdown # 2 – Write a sample payload (dashboard | calendar | chart | donut) bash "{baseDir}/scripts/write-sample-payload.sh" ./payload.json dashboard # 3 – Validate and create the guiro bash "{baseDir}/scripts/create-guiro.sh" --payload ./payload.json --idempotency-key run-001 ``` ```markdown The sample payloads are starting points. Replace the placeholder content with real data relevant to the user's request. ``` ```markdown Share the `url` with the user. Guiros are ephemeral — after `expires_at`, the link shows a standardized "This Guiro has Expired" page. ``` From `scripts/create-guiro.sh`: ```bash AUTH_HEADERS=(-H "X-API-Key: ${API_KEY}") validate_response="$(curl -sS -X POST "${API_ORIGIN}/v1/validate" "${AUTH_HEADERS[@]}" -H "Content-Type: application/json" --data-binary "@${PAYLOAD_FILE}")" ``` ```bash create_cmd=(curl -sS -X POST "${API_ORIGIN}/v1/create" "${AUTH_HEADERS[@]}" -H "Content-Type: application/json" --data-binary "@${PAYLOAD_FILE}") if [ -n "${IDEM ...[truncated 2417 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require explicit user confirmation immediately before uploading non-sample payloads, clearly stating: - The destination domain. - That the data is being sent to a third party. - That the resulting link is publicly accessible without login. - The expected expiration time. 2. Add local pre-upload checks for common sensitive values: - API keys, tokens, passwords, private keys, and connection strings. - Email addresses, phone numbers, government identifiers, and payment data. - Fields commonly named `secret`, `password`, `token`, `authorization`, or `api_key`. 3. Reject detected credentials by default and require deliberate override for other potentially sensitive categories. 4. Present a payload summary or redacted preview before transmission, including the file path, byte size, top-level fields, and destination endpoints. 5. Add payload size and schema restrictions so that the command cannot be used as an unrestricted arbitrary-file uploader. 6. Prefer private or authenticated share links when the service supports them. Otherwise, clearly label every returned URL as public. 7. Add revocation support and expose the exact expiry time to the user. 8. Document the third party's retention, validation-request handling, link entropy, access controls, and privacy policy. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/create-guiro.sh:17
Finding
API Key Is Propagated Through Child-Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/create-guiro.sh:17-19, 48-52`; `scripts/fetch-capabilities.sh:15-17`; `scripts/write-sample-payload.sh:58-62` **Vulnerability Type**: Sensitive credential exposure through process arguments **Risk Level**: Medium ### Complete Code Snippets From `scripts/create-guiro.sh`: ```bash --api-key) API_KEY="${2:-}" shift 2 ;; ``` ```bash if [ "${PREFLIGHT_CAPABILITIES}" = "true" ]; then preflight_args=(--out "${CAPABILITIES_FILE}") if [ -n "${API_KEY}" ]; then preflight_args+=(--api-key "${API_KEY}") fi bash "${SCRIPT_DIR}/fetch-capabilities.sh" "${preflight_args[@]}" >/dev/null 2>&1 || true fi ``` From `scripts/fetch-capabilities.sh`: ```bash --api-key) API_KEY="${2:-}" shift 2 ;; ``` From `scripts/write-sample-payload.sh`: ```bash if [ -n "${API_KEY}" ]; then args+=(--out "${CAPABILITIES_FILE}") args+=(--api-key "${API_KEY}") if bash "${SCRIPT_DIR}/fetch-capabilities.sh" "${args[@]}" >/dev/null 2>&1; then CAP_SOURCE="fetched" fetched="true" fi fi ``` ### Technical Analysis The scripts correctly support reading the API key from `GUIRO_API_KEY`, but they also accept `--api-key` and propagate the key to child scripts as a command-line argument. Secrets placed in argument vectors may be exposed through process-inspection interfaces, process monitoring, shell debugging, audit systems, crash diagnostics, or wrapper logs. The propagation is unnecessary because child processes normally inherit exported environment variables. A protected descriptor or secret manager would be preferable where stronger isolation is required. The key is also used in an HTTP request header, which is necessary for the declared authenticated API workflow and is sent only to the fixed HTTPS origin shown in the reviewed source. The vulnerability is specifically the local command-line propagation, not the required authenticated request. ### A ...[truncated 1122 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `--api-key` option from all scripts. 2. Do not place the credential in command arrays. Invoke the child script without a secret argument: ```bash preflight_args=(--out "${CAPABILITIES_FILE}") bash "${SCRIPT_DIR}/fetch-capabilities.sh" "${preflight_args[@]}" ``` 3. Read the credential only from `GUIRO_API_KEY` or a dedicated secret manager. Ensure the variable is exported only for the minimum process scope required: ```bash GUIRO_API_KEY="${API_KEY}" bash "${SCRIPT_DIR}/fetch-capabilities.sh" \ --out "${CAPABILITIES_FILE}" ``` 4. Where the execution environment exposes process environments to other users, use a protected file descriptor, operating-system credential store, or secret-manager integration instead of either arguments or broadly inherited environment variables. 5. Disable shell tracing around credential-handling code and ensure errors never print request headers. 6. Rotate any credential that may previously have appeared in process-monitoring or diagnostic logs. 7. Configure API keys with minimum service permissions, expiration, quotas, and revocation support. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The documented purpose understates important behaviors: authenticated API usage with GUIRO_API_KEY, capability discovery requests, and writing runtime metadata to local files. This mismatch can mislead users and reviewers about what the skill actually does, causing sensitive credentials or local state changes to be used without informed consent.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The documented purpose understates important behaviors: authenticated API usage with GUIRO_API_KEY, capability discovery requests, and writing runtime metadata to local files. This mismatch can mislead users and reviewers about what the skill actually does, causing sensitive credentials or local state changes to be used without informed consent.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill advertises shell-based scripts, local file writes, and API-driven network activity but does not declare any explicit tool scope such as permissions or allowed-tools. That creates an authorization and review gap: a host may grant broader capabilities than users expect, increasing the chance of unintended file modification or command execution during normal use.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill repeatedly emphasizes that the returned link is viewable by anyone with no login required, but it does not require a clear warning or confirmation before publishing potentially sensitive user data. In this context, the core feature is public sharing, so inadequate disclosure materially increases the risk of accidental data exposure to unintended recipients.

External Transmission

Medium
Category
Data Exfiltration
Content
AUTH_HEADERS=(-H "X-API-Key: ${API_KEY}")

validate_response="$(curl -sS -X POST "${API_ORIGIN}/v1/validate" "${AUTH_HEADERS[@]}" -H "Content-Type: application/json" --data-binary "@${PAYLOAD_FILE}")"

if echo "${validate_response}" | grep -Eq '"valid"[[:space:]]*:[[:space:]]*true'; then
  valid="true"
Confidence
95% confidence
Finding
This script transmits the entire user-supplied payload file and an API key to an external service for validation. Because the payload may contain sensitive structured data and the resulting share link is intended to be viewable without login, this creates a real data-exfiltration risk if the skill is used on confidential inputs or without explicit user consent.

External Transmission

Medium
Category
Data Exfiltration
Content
exit 1
fi

create_cmd=(curl -sS -X POST "${API_ORIGIN}/v1/create" "${AUTH_HEADERS[@]}" -H "Content-Type: application/json" --data-binary "@${PAYLOAD_FILE}")
if [ -n "${IDEMPOTENCY_KEY}" ]; then
  create_cmd+=(-H "Idempotency-Key: ${IDEMPOTENCY_KEY}")
fi
Confidence
97% confidence
Finding
This call uploads the validated payload to the external guiro.io API to create a shareable artifact, which operationalizes the exfiltration by publishing data to a remotely hosted resource accessible via a no-login link. In the context of an agent skill, this is more dangerous than ordinary API use because agents may process sensitive workspace data and users may not realize the action makes that data externally accessible.

Static analysis

No suspicious patterns detected.