Back to skill

Security audit

Forms

Security checks for vulnerabilities and agentic risk

Overview

This is a forms-building documentation skill with expected examples for local storage, integrations, and self-hosting, but users should handle form data and credentials carefully.

Install is reasonable for form-building help, but do not copy the integration and self-hosting snippets directly into production. Pin Docker images and npm package versions, keep API tokens server-side and out of URLs, avoid sending full submission contents to chat/email unless needed, and define consent, retention, deletion, encryption, and access controls before collecting real submissions.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T08 · Insecure Dependencies

Warning
Location
selfhosted.md:20
Finding
Mutable Docker Image Tags Permit Unreviewed Runtime Changes<![CDATA[ ## Vulnerability Details **File Location**: `selfhosted.md`, lines 20-65 **Vulnerability Type**: Unpinned third-party container dependencies **Risk Level**: Medium ### Vulnerable Code ```yaml # docker-compose.yml services: heyform: image: heyform/heyform:latest ports: - "3000:3000" environment: DATABASE_URL: postgres://... SESSION_SECRET: your-secret SMTP_HOST: smtp.example.com ``` ```yaml services: opnform-api: image: jhumanj/opnform-api:latest opnform-client: image: jhumanj/opnform-client:latest ``` ```bash docker run -d -p 3000:3000 \ -e DATABASE_URL=postgres://... \ formbricks/formbricks:latest ``` ### Technical Analysis The deployment examples use the mutable `latest` tag for HeyForm, OpnForm, and Formbricks images. A mutable tag does not identify a specific, previously reviewed artifact. Its associated image can change whenever the publisher updates the tag. Consequently, repeating the same documented deployment command can execute different code without any change to the Skill or deployment configuration. This weakens reproducibility and creates a supply-chain boundary in which a compromised publisher account, compromised registry, or malicious upstream release could replace a trusted image with attacker-controlled content. The issue is especially sensitive for form platforms because these containers may receive submitted personal data and access database URLs, session secrets, SMTP credentials, storage services, and mounted volumes. ### Attack Path 1. A user follows the documented deployment example and configures a service using an image tagged `latest`. 2. The upstream publisher account, build pipeline, or container registry is compromised, or an unsafe upstream release is assigned to the mutable tag. 3. The user initially pulls the image, redeploys the service, or runs an automated update process. 4. Docker resolves `latest` to the newly published, unreviewed image. 5. Attacker- ...[truncated 804 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace every mutable tag with a reviewed, immutable image digest, for example: ```yaml image: heyform/heyform@sha256:<reviewed-digest> ``` - If a human-readable version is retained, pin both the version and digest and treat the digest as authoritative. - Verify image signatures and provenance before deployment, such as with Sigstore/Cosign where the publisher supports it. - Scan pinned images for known vulnerabilities and secrets before promotion. - Use a controlled update process that reviews release notes, regenerates the digest, scans the new image, tests it, and requires approval before production rollout. - Run containers as non-root with a read-only root filesystem and minimal Linux capabilities. - Do not mount the Docker socket or unnecessary host directories. - Restrict outbound network access and provide only narrowly scoped credentials required by each service. ]]>

T08 · Insecure Dependencies

Warning
Location
selfhosted.md:53
Finding
Unpinned npm Packages May Resolve to Unreviewed Dependency Versions<![CDATA[ ## Vulnerability Details **File Location**: `selfhosted.md`, line 53 **Vulnerability Type**: Unpinned package installation **Risk Level**: Medium ### Vulnerable Code ```bash npm install survey-core survey-react-ui ``` ### Technical Analysis The installation command does not specify reviewed package versions and is not accompanied by a lockfile or integrity verification. It therefore resolves package versions from the npm registry at installation time. If a package publisher account, release pipeline, or transitive dependency is compromised, users following the instruction could install a release that differs from the one originally reviewed. npm packages may also define lifecycle scripts that execute during installation, giving a malicious package an execution opportunity in the developer or build environment. No evidence shows that the named packages are currently malicious. The finding concerns the unsafe, mutable dependency installation pattern. ### Attack Path 1. A user follows the documentation and runs the unpinned `npm install` command. 2. Before installation, an upstream package, publisher account, or transitive dependency is compromised and a malicious compatible version is published. 3. npm resolves the newly available version because no exact version or reviewed lockfile constrains resolution. 4. A malicious lifecycle script may execute during installation, or malicious library code becomes part of the application. 5. The malicious code operates with the permissions of the user, CI worker, build process, or deployed application. ### Impact Assessment An installation-time payload could access source code, environment variables, npm credentials, SSH material, CI secrets, and files available to the invoking account. A runtime payload could process or exfiltrate form submissions and application credentials. The exact scope is limited by the privileges and isolation of the developer environment, CI worker, or application process. Runni ...[truncated 96 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Specify reviewed exact versions rather than version ranges: ```bash npm install --save-exact survey-core@<reviewed-version> survey-react-ui@<reviewed-version> ``` - Generate and commit `package-lock.json`, then use `npm ci` in CI and production builds. - Review lockfile changes and verify package provenance and integrity before accepting updates. - Use automated dependency scanning and a controlled update process. - Where application compatibility permits, use `npm ci --ignore-scripts` or explicitly allow only required lifecycle scripts. - Run dependency installation in an isolated, non-privileged build environment without unnecessary secrets. - Configure the expected npm registry explicitly and use scoped registry settings to reduce dependency-confusion exposure. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
integrations.md:71
Finding
CRM API Credential Is Embedded in a URL Query String<![CDATA[ ## Vulnerability Details **File Location**: `integrations.md`, lines 71-74 **Vulnerability Type**: Sensitive token exposure through URL and process logging **Risk Level**: Low ### Vulnerable Code ```bash # Create person curl -X POST "https://api.pipedrive.com/v1/persons?api_token=${PIPEDRIVE_TOKEN}" \ -d '{"name":"John Doe","email":"user@example.com"}' ``` ### Technical Analysis The example expands `PIPEDRIVE_TOKEN` directly into the request URL. Query-string credentials are more likely than header-based credentials to be captured by local process inspection, shell debugging or audit telemetry, command logging, HTTP client diagnostics, proxy logs, gateway logs, and server access logs. HTTPS protects the URL while it is in transit between correctly configured endpoints, but it does not prevent credential exposure at either endpoint or in local and intermediary operational logs. Anyone obtaining the recorded token may reuse it until it is revoked or expires. ### Attack Path 1. A user exports `PIPEDRIVE_TOKEN` and executes the documented command. 2. The shell expands the variable into the command-line URL. 3. A local process monitor, audit system, verbose build log, proxy, gateway, or server access log records the full URL. 4. An unauthorized user or compromised monitoring system retrieves the logged token. 5. The attacker sends authenticated requests to the CRM API using the exposed credential. 6. The attacker performs operations allowed by the token's associated account and scope. ### Impact Assessment A disclosed token can permit unauthorized Pipedrive API operations within the permissions of the associated account. At minimum, the demonstrated API access creates CRM person records; broader access may be possible if the token grants additional API privileges. Potential consequences include unauthorized CRM modification, exposure of customer or lead data, spam records, operational disruption, and privacy impact. The scope is bounded by the t ...[truncated 99 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Prefer the provider's supported OAuth flow or an authorization header instead of placing credentials in the URL. - Use short-lived, narrowly scoped credentials whenever the service supports them. - Execute requests from a protected server-side integration rather than exposing CRM credentials to browser or client-side code. - Disable or redact verbose request logging and ensure URL query parameters are removed from proxy, gateway, tracing, and application logs. - Avoid commands that expose expanded secrets in process arguments. Use a protected configuration or secret-management mechanism supported by the client and service. - Restrict access to CI logs, shell audit records, and monitoring systems. - Rotate the token immediately if it may already have appeared in logs, and review API activity for unauthorized use. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (15)

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly recommends storing form submissions locally in `~/forms/submissions` but provides no guidance on access controls, encryption, retention, or the possibility that submissions may contain sensitive personal data. In a forms skill, collected responses commonly include names, emails, phone numbers, files, and other regulated data, so normalizing local storage without safeguards can lead to accidental exposure or mishandling.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The document provides numerous examples that send form-submission data, including emails, names, messages, and webhook payloads, to third-party services without any privacy notice, consent guidance, or data-minimization warning. In a forms skill, this is materially risky because operators may copy these patterns directly and transmit personal data to external processors without informing users or establishing an appropriate legal basis.

External Transmission

Medium
Category
Data Exfiltration
Content
### Mailchimp
```bash
# Add to list
curl -X POST "https://usX.api.mailchimp.com/3.0/lists/{list_id}/members" \
  -H "Authorization: Bearer ${MAILCHIMP_API_KEY}" \
  -d '{"email_address":"user@example.com","status":"subscribed"}'
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### ConvertKit
```bash
# Add subscriber + tag
curl -X POST "https://api.convertkit.com/v3/tags/{tag_id}/subscribe" \
  -d "api_secret=${CONVERTKIT_SECRET}&email=user@example.com"
```
Confidence
88% confidence
Finding
The ConvertKit example sends the API secret as form data rather than using a safer authorization header or server-side credential handling pattern, increasing the chance of accidental exposure in logs, proxies, debugging tools, or shell history. It also demonstrates transmitting user email to a third party without any nearby privacy warning, which is particularly relevant in a forms integration context.

External Transmission

Medium
Category
Data Exfiltration
Content
### Brevo (Sendinblue)
```bash
curl -X POST "https://api.brevo.com/v3/contacts" \
  -H "api-key: ${BREVO_API_KEY}" \
  -d '{"email":"user@example.com","listIds":[5]}'
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### HubSpot
```bash
# Create contact
curl -X POST "https://api.hubapi.com/crm/v3/objects/contacts" \
  -H "Authorization: Bearer ${HUBSPOT_TOKEN}" \
  -d '{"properties":{"email":"user@example.com","firstname":"John"}}'
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Pipedrive
```bash
# Create person
curl -X POST "https://api.pipedrive.com/v1/persons?api_token=${PIPEDRIVE_TOKEN}" \
  -d '{"name":"John Doe","email":"user@example.com"}'
```
Confidence
90% confidence
Finding
The Pipedrive example places the API token in the query string, which is a recognized insecure pattern because URLs are commonly captured in logs, browser history, proxy records, analytics, and monitoring systems. In a forms integration workflow, this can expose credentials that permit unauthorized access to CRM data or API actions.

External Transmission

Medium
Category
Data Exfiltration
Content
### Airtable
```bash
curl -X POST "https://api.airtable.com/v0/${BASE_ID}/${TABLE}" \
  -H "Authorization: Bearer ${AIRTABLE_TOKEN}" \
  -d '{"fields":{"Email":"user@example.com","Name":"John"}}'
```
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Notion
```bash
curl -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer ${NOTION_TOKEN}" \
  -H "Notion-Version: 2022-06-28" \
  -d '{"parent":{"database_id":"xxx"},"properties":{...}}'
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Telegram
```bash
curl "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
  -d "chat_id=${CHAT_ID}&text=New form: user@example.com"
```
Confidence
91% confidence
Finding
The Telegram example embeds the bot token directly in the URL path, which can leak via logs, monitoring tools, shell history, or accidental copy/paste, and it sends personal data in message text to a third-party messaging service. In a forms context, combining credential exposure risk with ad hoc notification of PII makes this more dangerous than a generic external-call example.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The sample API route collects and stores personal data (`email`, `name`, `message`) and sends a notification email, but it does not present any contextual warning in the example about sensitive-data handling, data minimization, retention, or avoiding submission of regulated data. In a forms skill, this omission is more dangerous because readers are likely to reuse the snippet for real customer or internal data collection, increasing the risk of privacy violations, overcollection, and unsafe handling of sensitive submissions.

Missing User Warnings

Low
Confidence
82% confidence
Finding
This markdown file demonstrates collecting personal data such as email and name and indicates submission to an API, but it does not mention any warning or disclosure about sending that data off-device. Under the markdown-file criteria, examples that affect user data or privacy should include some warning about the behavior.

Missing User Warnings

Low
Confidence
85% confidence
Finding
The schema explicitly specifies sending contact-form contents to an API endpoint, which involves transmitting user data. The surrounding markdown does not include any warning or disclosure about privacy, retention, or secure handling of submitted information.

Missing User Warnings

Low
Confidence
91% confidence
Finding
This markdown example performs a network request containing the user's email address, which is personally identifiable information. The file does not warn readers that asynchronous validation may disclose entered addresses to a server before final submission.

Static analysis

No suspicious patterns detected.