Back to skill

Security audit

Supabase Config — Safe Auth Settings

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Supabase Auth configuration helper with sensitive but purpose-aligned access and strong safeguards around remote writes.

Install only if you need an agent-assisted way to inspect or change Supabase Auth configuration. Use a fine-grained or short-lived token where possible, review the PINNED_REF edit, run dry runs first, and treat --apply as a real production configuration change.

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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (15)

Credential Access

High
Category
Privilege Escalation
Confidence
79% confidence
Finding

The skill requires a high-privilege Supabase access token and performs authenticated remote configuration writes. Even though it documents careful handling, any skill that consumes such a credential and can send network requests to a management API creates a meaningful credential-exposure and misuse surface if the agent runtime, prompts, or surrounding tooling are compromised.

Content

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

md
| Item | What this skill needs |
|---|---|
| Credentials | `SUPABASE_ACCESS_TOKEN`: a personal access token (`sbp_…`) from the dashboard, or a fine-grained token with `auth_config_write` + `project_admin_write`. Env var only. The script sends it in a header, in-process: never in argv, never printed, never written to disk. |
| Network out | `https://api.supabase.com` only. `--api-base` accepts nothing else except an `http://` loopback address (test servers). |
| Writes | **Remote Auth configuration** via `PATCH /v1/projects/<ref>/config/auth`, only with `--apply`. Without it, every write command is a dry run. Nothing else is written, locally or remotely. |
| Data persisted | None. `show` prints to stdout with secret-looking string fields (`*secret*`, `smtp_pass`, `*_key`, `*auth_token*`) replaced by `<redacted>`. |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
The script is `scripts/authcfg.py` (stdlib, Python 3.9+). Before first use, edit its `PINNED_REF` line to your project ref (§3).

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
The script is `scripts/authcfg.py` (stdlib, Python 3.9+). Before first use, edit its `PINNED_REF` line to your project ref (§3).

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
The script is `scripts/authcfg.py` (stdlib, Python 3.9+). Before first use, edit its `PINNED_REF` line to your project ref (§3).

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 · scripts/authcfg.py (reported line 15)May include surrounding context.

python
Guards (each refuses on absent, empty, wrong-typed input):
  * PINNED_REF below is the only project this copy of the script will touch.
    It is set by editing this file, never from the environment or a .env file.
  * The access token is read from SUPABASE_ACCESS_TOKEN and never printed.
  * The token is only sent to https://api.supabase.com, or to a loopback
    --api-base (for tests).

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 · scripts/authcfg.py (reported line 16)May include surrounding context.

python
Guards (each refuses on absent, empty, wrong-typed input):
  * PINNED_REF below is the only project this copy of the script will touch.
    It is set by editing this file, never from the environment or a .env file.
  * The access token is read from SUPABASE_ACCESS_TOKEN and never printed.
  * The token is only sent to https://api.supabase.com, or to a loopback
    --api-base (for tests).
  * A PATCH body contains only the keys you requested, and only those whose

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill clearly describes capabilities to read environment variables, invoke a local script, and make outbound network requests that can modify remote Supabase Auth configuration, yet it declares no explicit tool scope or permission boundaries. That mismatch increases the chance an agent platform will grant broader-than-intended access or fail to present appropriate user consent for sensitive operations.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · SKILL.md (reported line 44)May include surrounding context.

md
|---|---|---|
| `auth.site_url` | `http://127.0.0.1:3000` | Every magic link that fails the allow-list lands on localhost (§4) |
| `auth.additional_redirect_urls` | `["https://127.0.0.1:3000"]` → `uri_allow_list` | Your real callback URLs are gone |
| `auth.email.enable_confirmations` | `false` → `mailer_autoconfirm: true` | Sign-ups are confirmed without email proof |
| `auth.enable_signup` | `true` → `disable_signup: false` | Public sign-up reopens on an invite-only app |
| `auth.minimum_password_length` / `password_requirements` | `6` / `""` | Password policy weakened |
| `auth.jwt_expiry`, `email.otp_expiry` | `3600` | Custom session and OTP lifetimes reset |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · SKILL.md (reported line 71)May include surrounding context.

md
|---|---|---|
| `auth.site_url` | `http://127.0.0.1:3000` | Every magic link that fails the allow-list lands on localhost (§4) |
| `auth.additional_redirect_urls` | `["https://127.0.0.1:3000"]` → `uri_allow_list` | Your real callback URLs are gone |
| `auth.email.enable_confirmations` | `false` → `mailer_autoconfirm: true` | Sign-ups are confirmed without email proof |
| `auth.enable_signup` | `true` → `disable_signup: false` | Public sign-up reopens on an invite-only app |
| `auth.minimum_password_length` / `password_requirements` | `6` / `""` | Password policy weakened |
| `auth.jwt_expiry`, `email.otp_expiry` | `3600` | Custom session and OTP lifetimes reset |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · SKILL.md (reported line 94)May include surrounding context.

md
|---|---|---|
| `auth.site_url` | `http://127.0.0.1:3000` | Every magic link that fails the allow-list lands on localhost (§4) |
| `auth.additional_redirect_urls` | `["https://127.0.0.1:3000"]` → `uri_allow_list` | Your real callback URLs are gone |
| `auth.email.enable_confirmations` | `false` → `mailer_autoconfirm: true` | Sign-ups are confirmed without email proof |
| `auth.enable_signup` | `true` → `disable_signup: false` | Public sign-up reopens on an invite-only app |
| `auth.minimum_password_length` / `password_requirements` | `6` / `""` | Password policy weakened |
| `auth.jwt_expiry`, `email.otp_expiry` | `3600` | Custom session and OTP lifetimes reset |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · scripts/authcfg.py (reported line 497)May include surrounding context.

python
|---|---|---|
| `auth.site_url` | `http://127.0.0.1:3000` | Every magic link that fails the allow-list lands on localhost (§4) |
| `auth.additional_redirect_urls` | `["https://127.0.0.1:3000"]` → `uri_allow_list` | Your real callback URLs are gone |
| `auth.email.enable_confirmations` | `false` → `mailer_autoconfirm: true` | Sign-ups are confirmed without email proof |
| `auth.enable_signup` | `true` → `disable_signup: false` | Public sign-up reopens on an invite-only app |
| `auth.minimum_password_length` / `password_requirements` | `6` / `""` | Password policy weakened |
| `auth.jwt_expiry`, `email.otp_expiry` | `3600` | Custom session and OTP lifetimes reset |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · scripts/authcfg.py (reported line 534)May include surrounding context.

python
|---|---|---|
| `auth.site_url` | `http://127.0.0.1:3000` | Every magic link that fails the allow-list lands on localhost (§4) |
| `auth.additional_redirect_urls` | `["https://127.0.0.1:3000"]` → `uri_allow_list` | Your real callback URLs are gone |
| `auth.email.enable_confirmations` | `false` → `mailer_autoconfirm: true` | Sign-ups are confirmed without email proof |
| `auth.enable_signup` | `true` → `disable_signup: false` | Public sign-up reopens on an invite-only app |
| `auth.minimum_password_length` / `password_requirements` | `6` / `""` | Password policy weakened |
| `auth.jwt_expiry`, `email.otp_expiry` | `3600` | Custom session and OTP lifetimes reset |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · scripts/authcfg.py (reported line 637)May include surrounding context.

python
|---|---|---|
| `auth.site_url` | `http://127.0.0.1:3000` | Every magic link that fails the allow-list lands on localhost (§4) |
| `auth.additional_redirect_urls` | `["https://127.0.0.1:3000"]` → `uri_allow_list` | Your real callback URLs are gone |
| `auth.email.enable_confirmations` | `false` → `mailer_autoconfirm: true` | Sign-ups are confirmed without email proof |
| `auth.enable_signup` | `true` → `disable_signup: false` | Public sign-up reopens on an invite-only app |
| `auth.minimum_password_length` / `password_requirements` | `6` / `""` | Password policy weakened |
| `auth.jwt_expiry`, `email.otp_expiry` | `3600` | Custom session and OTP lifetimes reset |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · scripts/authcfg.py (reported line 655)May include surrounding context.

python
|---|---|---|
| `auth.site_url` | `http://127.0.0.1:3000` | Every magic link that fails the allow-list lands on localhost (§4) |
| `auth.additional_redirect_urls` | `["https://127.0.0.1:3000"]` → `uri_allow_list` | Your real callback URLs are gone |
| `auth.email.enable_confirmations` | `false` → `mailer_autoconfirm: true` | Sign-ups are confirmed without email proof |
| `auth.enable_signup` | `true` → `disable_signup: false` | Public sign-up reopens on an invite-only app |
| `auth.minimum_password_length` / `password_requirements` | `6` / `""` | Password policy weakened |
| `auth.jwt_expiry`, `email.otp_expiry` | `3600` | Custom session and OTP lifetimes reset |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% 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 · SKILL.md (reported line 55)May include surrounding context.

md
Traps around the prompt:

- `--yes` and `--output-format json` / `stream-json` auto-confirm.
- Declining the prompt exits **0**, like a successful push. The exit code does not tell you whether anything was written.
- The ref resolves `--project-ref` → `SUPABASE_PROJECT_ID` → `supabase/.temp/project-ref`. A stale env var wins over the link.
- A `[remotes.<name>]` block whose `project_id` equals the target is merged over the base before the push.

Static analysis

No suspicious patterns detected.