Back to skill

Security audit

neon-functions

Security checks for vulnerabilities and agentic risk

Overview

This is a documentation-style Neon Functions skill whose sensitive behaviors are expected for deploying public cloud functions, but users should review deploy, deletion, secret, and telemetry steps carefully.

Install this skill if you want an agent to help build and deploy Neon Functions. Before acting on generated steps, review any neon deploy, delete, trigger, env, telemetry, or MCP commands, keep secrets in gitignored env files or a secrets manager, and be deliberate about sending traces, prompts, outputs, or user identifiers to Sentry or Mastra.

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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (20)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/mastra-studio.md (reported line 79)May include surrounding context.

mastra auth whoami # shows your user + org id (org_…)

text

- **Access token (non-interactive):** `mastra auth tokens create <name>` prints a one-time secret (`sk_…`). This is your `MASTRA_PLATFORM_ACCESS_TOKEN`.
- **Project:** the interactive `mastra studio projects create` TUI is hard to script. Instead, register the project as part of a Studio deploy, which is non-interactive with `-y` and writes the project id to `.mastra-project.json`:

```bash

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/native-binaries.md (reported line 82)May include surrounding context.

text

```bash
npm run build:fn && neon deploy --env .env.local
neon functions deploy api --src dist/fn --no-bundle   # same thing, without neon.ts

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The description says 'Also use for Function Triggers' and then includes generic phrases like 'cron', 'cron job', 'on upload', 'DDoS protection', and 'production hardening' among activation triggers. Several of these are common concepts rather than narrowly scoped invocation phrases, which makes the activation boundary ambiguous and increases the risk of matching unrelated user requests.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · SKILL.md (reported line 26)May include surrounding context.

FIRST: Use the parent neon skill for a Neon overview, getting started with Neon, Neon development best practices, and more.

If the neon skill is not installed, fetch it from https://neon.com/docs/ai/skills/neon/SKILL.md or install it with:

bash
neon skills -s neon -y

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · SKILL.md (reported line 194)May include surrounding context.

md
Neon injects branch-scoped connection strings and service URLs at runtime — you don't declare these or pass them at deploy time:

| Variable                | Notes                                                                                              |
| ----------------------- | -------------------------------------------------------------------------------------------------- |
| `NEON_BRANCH`           | The branch **name** (e.g. `main`, `preview/foo`). Injected on every branch, including the default. |
| `DATABASE_URL`          | Pooled connection string. Use for most queries. Present only if the branch has Postgres.           |

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/function-triggers.md (reported line 224)May include surrounding context.

neon dev forwards x-neon-trigger-invocation-id, so you can simulate a tick:

bash
curl -X POST http://localhost:8787/cron \
  -H 'content-type: application/json' \
  -H 'x-neon-trigger-invocation-id: local-dev' \
  -d '{

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The document instructs users to export agent traces to a third-party observability service but does not explicitly warn that traces may contain prompts, model outputs, user data, secrets, or other sensitive metadata. In an AI-agent context, traces often capture high-value content, so omission of a privacy/data-sharing warning can lead to unintended disclosure to Mastra Cloud.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 163)May include surrounding context.

md
- **linux, arm64, glibc**, Node.js 24. A binary built for macOS or x64 cannot load there.
- The archive is extracted to `/opt/function`, a read-only filesystem. `import.meta.url` in the root `index.mjs` points there, so `new URL("./bin/tool", import.meta.url)` resolves to `/opt/function/bin/tool`.
- **Every file arrives with mode `644`.** Unix permission bits in the zip are dropped on extraction, and `chmod` in place fails with `EROFS`. A `.node` or `.so` loads fine (it is `dlopen`ed, not executed). Spawning a file from `/opt/function` fails with `EACCES`.
- `/tmp` is writable and mounted `noexec`: a copied binary still fails with `EACCES` after `chmod 755`.
- `/run` is a writable tmpfs that allows exec (about 990 MiB, backed by the function's 2048 MiB of memory).

The filesystem layout is observed behavior, not documented by Neon. Re-check it if spawning starts failing.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/native-binaries.md (reported line 18)May include surrounding context.

md
- **linux, arm64, glibc**, Node.js 24. A binary built for macOS or x64 cannot load there.
- The archive is extracted to `/opt/function`, a read-only filesystem. `import.meta.url` in the root `index.mjs` points there, so `new URL("./bin/tool", import.meta.url)` resolves to `/opt/function/bin/tool`.
- **Every file arrives with mode `644`.** Unix permission bits in the zip are dropped on extraction, and `chmod` in place fails with `EROFS`. A `.node` or `.so` loads fine (it is `dlopen`ed, not executed). Spawning a file from `/opt/function` fails with `EACCES`.
- `/tmp` is writable and mounted `noexec`: a copied binary still fails with `EACCES` after `chmod 755`.
- `/run` is a writable tmpfs that allows exec (about 990 MiB, backed by the function's 2048 MiB of memory).

The filesystem layout is observed behavior, not documented by Neon. Re-check it if spawning starts failing.

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/production-hardening.md (reported line 15)May include surrounding context.

md
Pick a row before writing code. Mixed routes: apply the matching row per
path, not one middleware for the whole Function.

| Caller                                                                                                           | What to do                                                                                                                                                                                                                                        | Do not                                                                                                                                  |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Trusted app server (Vercel/Netlify route, server action, queue worker) that finishes within that host's duration | The server calls the Function. Browser never sees the Function URL or the origin secret. Function returns 401 before any work.                                                                                                                    | Put the secret in client code. Proxy a long agent, WebSocket, or SSE stream through the app host without checking that host's duration. |
| Function Triggers only                                                                                           | `parseTriggerDelivery` (both types). Keep this path outside JWT and `X-Secret` middleware.                                                                                                                                                        | Require a user JWT 
...[truncated 25 chars]

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/production-hardening.md (reported line 15)May include surrounding context.

md
Pick a row before writing code. Mixed routes: apply the matching row per
path, not one middleware for the whole Function.

| Caller                                                                                                           | What to do                                                                                                                                                                                                                                        | Do not                                                                                                                                  |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Trusted app server (Vercel/Netlify route, server action, queue worker) that finishes within that host's duration | The server calls the Function. Browser never sees the Function URL or the origin secret. Function returns 401 before any work.                                                                                                                    | Put the secret in client code. Proxy a long agent, WebSocket, or SSE stream through the app host without checking that host's duration. |
| Function Triggers only                                                                                           | `parseTriggerDelivery` (both types). Keep this path outside JWT and `X-Secret` middleware.                                                                                                                                                        | Require a user JWT 
...[truncated 25 chars]

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/production-hardening.md (reported line 15)May include surrounding context.

md
Pick a row before writing code. Mixed routes: apply the matching row per
path, not one middleware for the whole Function.

| Caller                                                                                                           | What to do                                                                                                                                                                                                                                        | Do not                                                                                                                                  |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Trusted app server (Vercel/Netlify route, server action, queue worker) that finishes within that host's duration | The server calls the Function. Browser never sees the Function URL or the origin secret. Function returns 401 before any work.                                                                                                                    | Put the secret in client code. Proxy a long agent, WebSocket, or SSE stream through the app host without checking that host's duration. |
| Function Triggers only                                                                                           | `parseTriggerDelivery` (both types). Keep this path outside JWT and `X-Secret` middleware.                                                                                                                                                        | Require a user JWT 
...[truncated 25 chars]

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/production-hardening.md (reported line 17)May include surrounding context.

md
| Caller                                                                                                           | What to do                                                                                                                                                                                                                                        | Do not                                                                                                                                  |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Trusted app server (Vercel/Netlify route, server action, queue worker) that finishes within that host's duration | The server calls the Function. Browser never sees the Function URL or the origin secret. Function returns 401 before any work.                                                                                                                    | Put the secret in client code. Proxy a long agent, WebSocket, or SSE stream through the app host without checking that host's duration. |
| Function Triggers only                                                                                           | `parseTriggerDelivery` (both types). Keep this path outside JWT and `X-Secret` middleware.                                                                                                                                                        | Require a user JWT or `X-Secret` on the trigger path. Invent `x-neon-invocation-id`. Treat `invocation_id` as a secret.                 |
| Pu
...[truncated 25 chars]

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/production-hardening.md (reported line 17)May include surrounding context.

md
| Caller                                                                                                           | What to do                                                                                                                                                                                                                                        | Do not                                                                                                                                  |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Trusted app server (Vercel/Netlify route, server action, queue worker) that finishes within that host's duration | The server calls the Function. Browser never sees the Function URL or the origin secret. Function returns 401 before any work.                                                                                                                    | Put the secret in client code. Proxy a long agent, WebSocket, or SSE stream through the app host without checking that host's duration. |
| Function Triggers only                                                                                           | `parseTriggerDelivery` (both types). Keep this path outside JWT and `X-Secret` middleware.                                                                                                                                                        | Require a user JWT or `X-Secret` on the trigger path. Invent `x-neon-invocation-id`. Treat `invocation_id` as a secret.                 |
| Pu
...[truncated 25 chars]

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/production-hardening.md (reported line 18)May include surrounding context.

md
| Caller                                                                                                           | What to do                                                                                                                                                                                                                                        | Do not                                                                                                                                  |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Trusted app server (Vercel/Netlify route, server action, queue worker) that finishes within that host's duration | The server calls the Function. Browser never sees the Function URL or the origin secret. Function returns 401 before any work.                                                                                                                    | Put the secret in client code. Proxy a long agent, WebSocket, or SSE stream through the app host without checking that host's duration. |
| Function Triggers only                                                                                           | `parseTriggerDelivery` (both types). Keep this path outside JWT and `X-Secret` middleware.                                                                                                                                                        | Require a user JWT or `X-Secret` on the trigger path. Invent `x-neon-invocation-id`. Treat `invocation_id` as a secret.                 |
| Pu
...[truncated 25 chars]

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/production-hardening.md (reported line 18)May include surrounding context.

md
| Caller                                                                                                           | What to do                                                                                                                                                                                                                                        | Do not                                                                                                                                  |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Trusted app server (Vercel/Netlify route, server action, queue worker) that finishes within that host's duration | The server calls the Function. Browser never sees the Function URL or the origin secret. Function returns 401 before any work.                                                                                                                    | Put the secret in client code. Proxy a long agent, WebSocket, or SSE stream through the app host without checking that host's duration. |
| Function Triggers only                                                                                           | `parseTriggerDelivery` (both types). Keep this path outside JWT and `X-Secret` middleware.                                                                                                                                                        | Require a user JWT or `X-Secret` on the trigger path. Invent `x-neon-invocation-id`. Treat `invocation_id` as a secret.                 |
| Pu
...[truncated 25 chars]

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/sentry.md (reported line 21)May include surrounding context.

md
### Environment variables

| Variable                    | Purpose                                                                                                                        |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `SENTRY_DSN`                | Project DSN; keep it configurable through the deployment environment.                                                          |
| `SENTRY_RELEASE`            | Optional release identifier such as a commit SHA — unlocks regression detection.                                               |

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The guidance encourages enabling AI SDK telemetry and setting conversation/user identifiers, but the privacy warning is brief and easy to miss relative to the operational setup detail. In this context, prompts, outputs, and user IDs may be sent to Sentry by default, which can expose sensitive user content or personal data to a third-party telemetry system if deployers do not explicitly disable those fields.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation explicitly recommends authenticating SSE with a ?token= query parameter but does not warn that query strings are commonly exposed in browser history, server/access logs, reverse proxies, analytics tooling, and referrer leakage. Because this skill is about deploying internet-facing long-lived HTTP endpoints, users may copy this pattern directly into production and inadvertently leak bearer-style credentials.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/production-hardening.md:111