Back to skill

Security audit

Firestore

Security checks for vulnerabilities and agentic risk

Overview

The skill is transparent about using Google Cloud credentials for Firestore CRUD, but its curl-based command construction creates a real review-worthy risk around shell injection and high-impact database actions.

Review this skill before installing. Use it only with a dedicated least-privilege service account and a non-production or tightly scoped project. Carefully inspect generated curl commands, especially any values containing quotes, dollar signs, backticks, newlines, semicolons, ampersands, or unusual path/query characters, because the current examples do not provide strong shell-injection safeguards.

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
examples.md:118
Finding
Shell Command Injection Through Unsafely Interpolated Firestore Input<![CDATA[ ## Vulnerability Details **File Location**: `examples.md:118-139` (operational example), reinforced by command-construction instructions in `SKILL.md:102-111` **Vulnerability Type**: Shell command injection caused by unsafe interpolation into JSON bodies and URLs **Risk Level**: Medium ### Vulnerable Code The skill instructs the agent to construct a shell command from requested Firestore values and identifiers: ```markdown 3. **Construct the curl command** — Build the appropriate curl command based on the operation: - Use the correct HTTP method (POST for create/query, GET for read, PATCH for update, DELETE for delete) - Include the `Authorization: Bearer $ACCESS_TOKEN` header - Set `Content-Type: application/json` for requests with body - Use the correct API endpoint for the project and collection ``` The corresponding operational example directly embeds document data and a document identifier into shell syntax: ```markdown ### Example 5: Creating a document with a specific ID **User prompt:** "Create a settings document with ID app_config containing theme as dark and notifications enabled" **Expected agent behavior:** 1. Run `gcloud config list --format='text(core.account,core.project)'` and show the active context to the user 2. Get the project ID from the output 3. Construct the curl command with documentId parameter: ```bash ACCESS_TOKEN=$(gcloud auth print-access-token) curl -X POST \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "fields": { "theme": { "stringValue": "dark" }, "notifications": { "booleanValue": true } } }' \ "https://firestore.googleapis.com/v1/projects/my-project/databases/(default)/documents/settings?documentId=app_config" ``` 4. Present the command to the user 5. **Wait for user approval** before executing (this is a create operation) ``` ### Technical Analysis Firestore field values are placed in ...[truncated 2740 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Use a trusted JSON serializer** - Construct request bodies with a tool such as `jq`, using `--arg`, `--argjson`, and structured object construction. - Never concatenate user-controlled values directly into shell-quoted JSON. - Store the generated body in a temporary file with restrictive permissions or pass serialized output through standard input. 2. **Encode URL components** - Percent-encode project IDs, database IDs, collection names, document IDs, field paths, and query parameter values independently. - Prefer `curl --get --data-urlencode` for query parameters where supported. - Do not treat URL quoting as shell-safety or URL encoding. 3. **Apply strict identifier validation** - Validate project and resource identifiers against documented Google Cloud and Firestore formats. - Reject shell metacharacters, control characters, line breaks, command-substitution syntax, and unexpected path separators. - Use allowlists rather than attempting to enumerate dangerous characters. 4. **Avoid dynamic shell evaluation** - Invoke `curl` through an argument-array API when implementation tooling permits. - Never use `eval`, `sh -c`, or equivalent re-parsing of generated command strings. - If commands must be displayed for approval, retain a structured argument list and execute that exact structure rather than re-parsing displayed text. 5. **Strengthen approval output** - Display user-controlled values separately from the rendered command. - Clearly identify all target resource components and whether the operation is read-only or destructive. - Preserve the existing active-account and project confirmation requirements, but do not rely on approval as the primary injection defense. 6. **Add adversarial tests** - Test values containing single and double quotes, backticks, dollar signs, command substitutions, newlines, backslashes, Unicode control characters, ampersands, semicolons, and U ...[truncated 126 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Credential Access

High
Category
Privilege Escalation
Content
## Credentials & Environment

This skill uses OAuth 2.0 access tokens generated by `gcloud auth print-access-token`. The token is valid for a limited time (typically 1 hour) and inherits the permissions of the authenticated Google Cloud account.

This skill must run only with a dedicated service account context. Do not use personal user credentials or broad admin identities.
Confidence
88% confidence
Finding
The skill is designed to obtain and use live OAuth access tokens from the local gcloud context, which grants the skill direct access to whatever Firestore permissions the active identity holds. Even though the document includes warnings and recommends service accounts, the mechanism still exposes a high-value credential path that could enable unauthorized data access or modification if the agent mishandles commands, context, or output.

Credential Access

High
Category
Privilege Escalation
Content
This skill must run only with a dedicated service account context. Do not use personal user credentials or broad admin identities.

**Before any operation, generate a fresh access token:**
```bash
ACCESS_TOKEN=$(gcloud auth print-access-token)
```
Confidence
93% confidence
Finding
This line provides a concrete command for generating a fresh access token and storing it in an environment variable, making credential acquisition operationally trivial. In the context of an agent skill with command execution capability, that creates a real risk of credential misuse, accidental disclosure, or use against the wrong project if safeguards fail.

Credential Access

High
Category
Privilege Escalation
Content
1. **Check active context** — Run `gcloud config list --format='text(core.account,core.project)'` to display the active account and project. Present this to the user so they are aware of which credentials and project will be used.

2. **Generate access token** — Always start by obtaining a fresh access token:
   ```bash
   ACCESS_TOKEN=$(gcloud auth print-access-token)
   ```
Confidence
91% confidence
Finding
Embedding token generation as a mandatory workflow step normalizes credential retrieval for every operation, including reads, which broadens opportunities for sensitive data access. Because the token inherits all permissions of the active Google Cloud account, any mistake in account selection, project targeting, or downstream command handling can have significant impact on confidentiality and integrity.

Credential Access

High
Category
Privilege Escalation
Content
gcloud config list --format='text(core.account,core.project)'
```

## Access Token

Before any Firestore API request, generate a fresh access token:
```bash
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## Access Token

Before any Firestore API request, generate a fresh access token:
```bash
ACCESS_TOKEN=$(gcloud auth print-access-token)
```
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Content
- **Use proper JSON formatting** — Firestore requires specific field value types (stringValue, booleanValue, integerValue, etc.).
- **Document ID generation** — When creating documents, if you don't specify `?documentId=YOUR_ID` in the URL, Firestore will automatically generate a unique document ID.
- **Include field paths in updateMask** — When updating, use `updateMask.fieldPaths` to specify which fields to update.
- **Never execute any command autonomously** — always present the full curl command to the user and wait for explicit approval before running it, including read-only operations.
- **Parse responses carefully** — Firestore returns data in a nested format with typed values.
- **Verify project ID** — Always confirm you're targeting the correct project before executing commands.
Confidence
80% confidence
Finding
Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.

External Transmission

Medium
Category
Data Exfiltration
Content
**Expected agent behavior:**
1. Run `gcloud config list --format='text(core.account,core.project)'` and show the active context to the user
2. Get the project ID from the output (e.g., `my-project`)
3. Construct the curl command:
   ```bash
   ACCESS_TOKEN=$(gcloud auth print-access-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.

Static analysis

No suspicious patterns detected.