Back to skill

Security audit

Coda.io

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate Coda API helper, but it exposes live delete, sharing, publishing, and automation actions without built-in confirmation or strong scoping.

Install only if you are comfortable giving the agent a Coda API token with access to your docs. Use the least-privilege token/account available, prefer read-first workflows, and manually confirm any delete, share, publish, permission, or automation action before it is run.

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/coda.sh:50
Finding
Unsafe JSON Construction from Untrusted Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/coda.sh`, lines 50–51, 151, and 157 **Vulnerability Type**: Improper JSON escaping and insufficient input validation **Risk Level**: Medium ### Vulnerable Code At lines 50–51, document properties are inserted directly into a JSON string: ```bash body="{\"title\":\"$1\"}" [[ -n "${2:-}" ]] && body="{\"title\":\"$1\",\"folderId\":\"$2\"}" ``` At line 151, folder properties are handled in the same way: ```bash _post -d "{\"name\":\"$1\",\"workspaceId\":\"$2\"}" "$BASE/folders" ``` At line 157, permission properties are directly interpolated: ```bash _post -d "{\"access\":\"$3\",\"principal\":{\"type\":\"email\",\"email\":\"$2\"}}" "$BASE/docs/$1/acl/permissions" ``` ### Technical Analysis The script constructs JSON by embedding command-line arguments directly between JSON quotation marks. It does not apply JSON-aware escaping to quotation marks, backslashes, control characters, or structural characters supplied in those arguments. An argument containing a quotation mark and JSON syntax can terminate the intended string value and introduce or modify object properties. Depending on the Coda API's JSON parser, schema validation, and treatment of duplicate properties, this can result in malformed requests or request semantics that differ from the command invocation presented to the user. The permission operation is particularly sensitive because both the requested access level and recipient email are inserted without escaping or validation. The script also does not enforce the documented `readonly`, `write`, or `comment` allowlist before submitting the request. This is JSON/data injection rather than shell-command injection. The interpolated content remains an argument passed to `curl`, and the reviewed code does not use `eval` or execute the resulting JSON as shell syntax. ### Attack Path 1. An attacker influences a document title, folder name, workspace identifier, recipient email, access v ...[truncated 1785 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Construct every request body with a JSON-aware serializer instead of manual string interpolation. For example: ```bash body="$(jq -n --arg title "$1" '{title: $title}')" if [[ -n "${2:-}" ]]; then body="$(jq -n \ --arg title "$1" \ --arg folderId "$2" \ '{title: $title, folderId: $folderId}')" fi _post -d "$body" "$BASE/docs" ``` Apply the same approach to folder creation: ```bash body="$(jq -n \ --arg name "$1" \ --arg workspaceId "$2" \ '{name: $name, workspaceId: $workspaceId}')" _post -d "$body" "$BASE/folders" ``` For document sharing, validate the access value and serialize all fields safely: ```bash case "$3" in readonly|write|comment) ;; *) echo "Error: access must be readonly, write, or comment." >&2 exit 1 ;; esac body="$(jq -n \ --arg access "$3" \ --arg email "$2" \ '{access: $access, principal: {type: "email", email: $email}}')" _post -d "$body" "$BASE/docs/$1/acl/permissions" ``` Additional hardening measures should include: 1. Validate resource identifiers against the documented Coda identifier format where practical. 2. Validate email addresses before permission mutations. 3. Reject control characters and unreasonable argument lengths. 4. Require explicit confirmation before destructive or access-control operations when the script is used interactively. 5. Add regression tests using quotation marks, backslashes, newlines, and JSON structural characters in every text argument. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill explicitly instructs use of shell scripts and direct curl commands but does not declare any tool scope or allowed-tools boundary. That omission weakens containment and review because an agent may invoke shell-based operations with network access and credentials without an explicit permission model.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill promotes write, update, delete, and share capabilities against live Coda documents but does not warn about destructive or externally visible effects. In an agent setting, that increases the chance of unintended data modification, permission changes, or disclosure because risky operations are normalized without requiring explicit user confirmation.

External Transmission

Medium
Category
Data Exfiltration
Content
- **valueFormat**: `simple` (default), `simpleWithArrays`, `rich` for structured data.
- **Doc ID from URL**: `https://coda.io/d/Title_d<DOC_ID>` → the part after `_d` is the doc ID.

## Direct curl (when script doesn't cover it)

```bash
curl -s -H "Authorization: Bearer $CODA_API_TOKEN" \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The reference documents destructive and privilege-changing operations such as deleting docs, folders, pages, rows, changing ACL permissions, publishing, and triggering automations, but it provides no safety guidance about confirmation, authorization checks, or the consequences of invoking them. In an agent skill context, this increases the chance that an LLM-driven workflow will perform high-impact actions from ambiguous or prompt-injected user requests without adequate guardrails.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The script provides a delete-doc command that irreversibly deletes a document, but there is no confirmation prompt and no nearby warning comment or user-facing disclosure beyond the terse usage text. Under the code-file criteria, destructive operations should have some visible warning unless clearly disclosed; here the help text also omits any caution about deletion impact.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
Both delete-row and delete-rows perform destructive API deletions, but the script does not present a confirmation prompt or any warning comment/help text indicating that rows will be permanently removed. The current usage strings describe arguments only and do not disclose the destructive nature of the action.

Static analysis

No suspicious patterns detected.