Back to skill

Security audit

Supabase Hakke

Security checks for vulnerabilities and agentic risk

Overview

This Supabase skill is mostly a coherent setup guide, but it includes unsafe database and credential-handling examples that could create real account or tenant-isolation risk if copied directly.

Review before installing or using this skill. Do not copy the password123 admin-user SQL into any real Supabase project, treat SUPABASE_SERVICE_ROLE_KEY as backend-only secret material, pin or verify CLI installation, and add explicit safeguards before running database reset or SECURITY DEFINER examples.

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
SKILL.md:26
Finding

Unpinned Global Installation of the Supabase CLI

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 26-30
Vulnerability Type: Unpinned third-party dependency installed globally
Risk Level: Medium

Vulnerable Code:

bash
# Supabase CLI (ya instalado)
supabase --version

# Si no está instalado
npm install -g supabase

Technical Analysis

The instructions install the mutable latest version of the supabase npm package globally. No reviewed version, lockfile, or integrity constraint is specified. Consequently, the package and any lifecycle scripts executed by npm may differ from the version originally assessed.

Global installation increases the potential effect because package files are added to the user's global executable environment. This does not establish that the named package is malicious, but it creates avoidable supply-chain exposure if its registry account, release process, or transitive dependency chain is compromised.

Attack Path

  1. An attacker compromises the relevant package publication process or one of its dependencies.
  2. The attacker publishes a modified release containing a malicious lifecycle script or executable payload.
  3. A user follows the skill instructions and runs npm install -g supabase.
  4. npm retrieves the mutable current release and executes applicable installation scripts with the invoking user's privileges.
  5. The payload can access data and modify files available to that user and can place executables in the global npm environment.

Impact Assessment

Successful exploitation could execute arbitrary code with the privileges of the user running npm. The accessible scope could include project source code, local environment variables, Supabase credentials, Vercel credentials, and files writable by that user. If the command is run with elevated privileges, the impact could extend to system-wide files and executables.

Remediation
View remediation

Remediation Suggestions

  • Pin the CLI to a specific, reviewed version, for example: npm install -g supabase@1.2.3.
  • Establish a controlled process for reviewing and updating the pinned version.
  • Prefer the vendor's documented installation mechanism and verify package provenance or integrity where supported.
  • Avoid elevated privileges during package installation.
  • Where practical, use a project-local, lockfile-controlled dependency instead of modifying the global executable environment.
  • Disable lifecycle scripts during installation when they are not required and compatibility has been verified.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:94
Finding

Administrative User Example Uses a Predictable Password

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 94-102
Vulnerability Type: Predictable credential in a security-sensitive account-creation example
Risk Level: High

Vulnerable Code:

sql
-- In Supabase Dashboard SQL Editor
INSERT INTO auth.users (email, encrypted_password, email_confirmed_at)
VALUES (
  'user@example.com',
  crypt('password123', gen_salt('bf')),
  NOW()
);

Technical Analysis

The documented SQL directly creates an authentication record with the known password password123 and immediately sets email_confirmed_at. Although the password is hashed before storage, hashing does not protect an account when the original password is publicly known and predictable.

The example is presented as an administrative user-creation operation and does not explicitly require replacing the password, generating a high-entropy temporary secret, or forcing a password reset. Copying it literally could therefore create a confirmed account that can be accessed with credentials visible in the skill documentation. Direct insertion into Supabase authentication internals may also bypass supported account-provisioning workflows and their associated validation or lifecycle behavior.

Attack Path

  1. An operator copies the SQL example into the Supabase Dashboard SQL Editor.
  2. The database creates user@example.com with the password password123.
  3. The account is marked as email-confirmed immediately.
  4. An attacker who discovers or guesses that the documented example was used attempts authentication with the published credentials.
  5. If the credentials were not changed, the attacker obtains the account's authenticated session and can exercise all permissions granted to that user.

Impact Assessment

Exploitation grants the privileges assigned to the affected application account. Depending on application authorization and RLS policies, this could expose or permit modification of ...[truncated 236 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace direct insertion into auth.users with the supported Supabase administrative user-management API.
  • Generate a unique, cryptographically strong temporary password rather than documenting a reusable literal password.
  • Require a password reset or secure invitation flow before granting normal access.
  • Do not automatically mark an account as confirmed unless the provisioning workflow explicitly requires and authorizes it.
  • Add a prominent warning that example identifiers and credentials must never be copied into a real environment.
  • Apply least-privilege roles to newly provisioned users and audit existing environments for accounts created with the documented credentials.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:203
Finding

Privilege-Bearing PostgreSQL Functions Lack a Hardened Execution Context

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 203-233
Vulnerability Type: Unsafe PostgreSQL SECURITY DEFINER configuration
Risk Level: Medium

Vulnerable Code:

sql
-- Function to get current tenant
CREATE OR REPLACE FUNCTION current_tenant_id()
RETURNS uuid AS $$
BEGIN
  RETURN (auth.jwt()->>'tenant_id')::uuid;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- RLS Policy example
CREATE POLICY "Users can only see own tenant data"
ON appointments
FOR ALL
USING (tenant_id = current_tenant_id());
sql
-- Check subscription status
CREATE OR REPLACE FUNCTION has_active_subscription()
RETURNS boolean AS $$
DECLARE
  tenant_record tenants%ROWTYPE;
BEGIN
  SELECT * INTO tenant_record
  FROM tenants
  WHERE id = current_tenant_id();

  RETURN tenant_record.subscription_status = 'active';
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

Technical Analysis

Both functions execute with the database privileges of their owner because they are declared SECURITY DEFINER. Neither function fixes its search_path, and the subscription function references tenants and current_tenant_id() without schema qualification. The documentation also does not revoke the default function-execution privilege from PUBLIC or restrict execution to explicitly authorized roles.

Privileged PostgreSQL functions should not resolve security-sensitive objects through a caller-influenced schema search path. If an attacker can create objects in a schema searched before the intended schema, unqualified names can resolve to attacker-controlled objects while the function runs under the owner's privileges. Exploitability therefore depends on the deployed schema search path, object-creation rights, function ownership, and grants.

The first function contains fewer unqualified application objects, but it is still unnecessarily granted a definer context without documenting why elevated ex ...[truncated 1512 chars]

Remediation
View remediation

Remediation Suggestions

  • Use SECURITY INVOKER unless elevated owner privileges are strictly necessary.
  • For every required SECURITY DEFINER function, set a fixed trusted search_path, with temporary or user-writable schemas excluded.
  • Schema-qualify all relations, functions, types, and other referenced objects, such as public.tenants and the intended schema-qualified tenant function.
  • Revoke default execution from PUBLIC, then grant EXECUTE only to the minimum required application roles.
  • Assign ownership to a dedicated, minimally privileged role rather than a superuser or broad administrative role.
  • Review schema CREATE privileges and remove object-creation rights from untrusted roles in schemas used for privileged object resolution.
  • Add tests proving that callers cannot cross tenant boundaries or alter function resolution through their effective search path.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (4)

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The skill instructs users to place SUPABASE_SERVICE_ROLE_KEY in .env.local without sufficiently constraining its use, while also presenting adjacent client and deployment guidance. Service-role keys bypass Row Level Security and grant broad database access, so weak separation between server-only and client-facing configuration can lead to accidental exposure in frontend code, logs, builds, or misconfigured hosting.

Content

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

Environment Variables

.env.local

bash
NEXT_PUBLIC_SUPABASE_URL=https://<project>.supabase.co

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file describes a safety-critical operation, supabase db reset, which can destroy local database state. Although the heading says "DEV ONLY," it does not clearly warn about data loss or irreversible effects, so the user-facing documentation lacks a strong disclosure of the risk.

Content

No source excerpt is available for this finding.

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 · SKILL.md (reported line 174)May include surrounding context.

Invoke Function

bash
curl -i -L --request POST 'https://<project>.supabase.co/functions/v1/<function-name>' \
  --header 'Authorization: Bearer <anon-key>' \
  --header 'Content-Type: application/json' \
  --data '{"name":"Functions"}'

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The document includes Spanish-language instructional content such as "Supabase integration específica para proyectos de Hakke Studio" and other Spanish comments, which can amount to a language/locale preference being imposed on users. The file does not offer an opt-in language choice or explain that the skill is intentionally limited to Spanish-speaking users.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.