Back to skill

Security audit

Forms for Google Drive

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for Google Forms automation, but it can route form contents and response exports through a third-party API without strong privacy scoping or confirmation guidance.

Review this before installing if your forms may contain personal, employee, customer, health, or regulated data. Only use it when you intentionally want Google Forms data handled through api.gformsfree.com, keep the API key secret, and treat exported download links as sensitive even though the documented expiry is 10 minutes.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (13)

Vague Triggers

Medium
Confidence
95% confidence
Finding
The skill description is broad enough to trigger on many generic requests about surveys, forms, analysis, or exports, increasing the chance the agent invokes this third-party integration when the user did not explicitly intend external processing. In this context, overbroad routing is risky because the skill can transmit form metadata and response data to an external service using a managed OAuth bridge.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill handles potentially sensitive form responses and exports them through a remote API, but the description does not clearly warn that user data and survey responses are transmitted to a third-party service. This can lead to privacy violations or uninformed consent issues, especially for forms containing personal, health, HR, or customer data.

External Transmission

Medium
Category
Data Exfiltration
Content
```python
import urllib.request, os, json
req = urllib.request.Request('https://api.gformsfree.com/skill/forms/list')
req.add_header('Authorization', f'Bearer {os.environ["GFORMS_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
```
Confidence
91% confidence
Finding
This example sends an authorization bearer token to an external domain and retrieves user-associated Google Forms data through a third-party API. External transmission is expected for this skill, but it remains a real security/privacy concern because the integration can access account data and route it off-platform.

External Transmission

Medium
Category
Data Exfiltration
Content
## Base URL

```
https://api.gformsfree.com/skill
```

## Authentication
Confidence
90% confidence
Finding
The declared base URL confirms that all operations are performed against an external service rather than directly within the local agent environment. In context, this increases privacy and supply-chain risk because form metadata, responses, and OAuth-mediated operations depend on a third-party endpoint.

External Transmission

Medium
Category
Data Exfiltration
Content
```python
import urllib.request, os, json
req = urllib.request.Request('https://api.gformsfree.com/skill/forms/list')
req.add_header('Authorization', f'Bearer {os.environ["GFORMS_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
```
Confidence
91% confidence
Finding
Listing forms transmits the bearer token to the external API and can disclose the existence and metadata of a user's forms to that service. While this is part of intended functionality, it is still a real exposure that should be disclosed and gated by user intent.

External Transmission

Medium
Category
Data Exfiltration
Content
```python
import urllib.request, os, json
req = urllib.request.Request('https://api.gformsfree.com/skill/forms/FORM_ID')
req.add_header('Authorization', f'Bearer {os.environ["GFORMS_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
```
Confidence
91% confidence
Finding
Fetching a specific form through the external API may transmit form structure, titles, questions, and related metadata to a third-party service. This is especially sensitive if forms contain internal business, employee, or regulated information.

External Transmission

Medium
Category
Data Exfiltration
Content
]
}).encode()
req = urllib.request.Request(
  'https://api.gformsfree.com/skill/forms/create',
  data=data, method='POST'
)
req.add_header('Authorization', f'Bearer {os.environ["GFORMS_API_KEY"]}')
Confidence
92% confidence
Finding
Creating a form sends user-provided title, description, and question contents to an external API along with the authorization token. If users include confidential prompts or regulated data in form definitions, that content is disclosed to the service operator.

External Transmission

Medium
Category
Data Exfiltration
Content
```python
import urllib.request, os, json
req = urllib.request.Request('https://api.gformsfree.com/skill/forms/FORM_ID/responses')
req.add_header('Authorization', f'Bearer {os.environ["GFORMS_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
```
Confidence
95% confidence
Finding
Listing responses is more sensitive than form metadata because response payloads can contain personal data, free-text submissions, and other confidential information. Sending this through the external API materially increases privacy and compliance risk if users are not clearly informed.

External Transmission

Medium
Category
Data Exfiltration
Content
```python
import urllib.request, os, json
req = urllib.request.Request('https://api.gformsfree.com/skill/forms/FORM_ID/summary')
req.add_header('Authorization', f'Bearer {os.environ["GFORMS_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
```
Confidence
96% confidence
Finding
Summarization sends or processes all form responses through the external service, potentially exposing large volumes of sensitive respondent data for secondary processing. The natural-language summary feature can encourage broad analysis of content without adequate privacy disclosure.

External Transmission

Medium
Category
Data Exfiltration
Content
import urllib.request, os, json
data = json.dumps({"formId": "FORM_ID"}).encode()
req = urllib.request.Request(
  'https://api.gformsfree.com/skill/forms/export',
  data=data, method='POST'
)
req.add_header('Authorization', f'Bearer {os.environ["GFORMS_API_KEY"]}')
Confidence
95% confidence
Finding
Exporting responses transmits a request to package form data and results in a downloadable spreadsheet, increasing the risk of bulk data disclosure. In this context, exports are particularly sensitive because they consolidate potentially personal or regulated information into an easily shareable file.

External Transmission

Medium
Category
Data Exfiltration
Content
**Response:**
```json
{
  "downloadUrl": "https://api.gformsfree.com/skill/files/xxx.xlsx",
  "expiresIn": 600
}
```
Confidence
94% confidence
Finding
The returned downloadUrl is an externally hosted link to a spreadsheet containing form responses, creating a direct exfiltration path for bulk data. Even though it expires, anyone who obtains the URL within its lifetime may access the exported dataset if no additional authentication is required.

External Transmission

Medium
Category
Data Exfiltration
Content
```python
import urllib.request, os, json
req = urllib.request.Request('https://api.gformsfree.com/skill/auth/check')
req.add_header('Authorization', f'Bearer {os.environ["GFORMS_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
```
Confidence
88% confidence
Finding
The auth-check example sends the bearer token to the external API, confirming the key's validity and potentially exposing account linkage to the service. This is expected behavior, but it still represents external secret use and should be disclosed as such.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The inline agent instruction says to 'Confirm twice before deleting any form,' which implies the skill supports form deletion. However, the documented API surface in this file includes listing, getting, creating, listing responses, summarizing, exporting, and auth checking, but no delete endpoint or delete behavior is described. This is an active contradiction in the skill documentation about what the skill can do.

Static analysis

No suspicious patterns detected.