transactions
CRITICAL
Missing AS RESTRICTIVE enforcement. Existing policies are permissive, allowing bypass via overlapping roles.
-- REMEDIATION: Cross-Tenant Mutation (IDOR) Hardening
-- Logic: Enforce Restrictive JWT Claim Validation
DROP POLICY IF EXISTS "tenant_isolation_policy" ON "public"."transactions";
CREATE POLICY "tenant_isolation_policy"
ON "public"."transactions"
AS RESTRICTIVE -- Ensures no other policy can accidentally grant access
FOR ALL
TO authenticated
USING (
tenant_id = (select auth.jwt() ->> 'tenant_id')::uuid
)
WITH CHECK (
tenant_id = (select auth.jwt() ->> 'tenant_id')::uuid
);
-- Note: Validation shifted from auth.uid() to tenant_id claim to
-- prevent role-escalation and orphan record creation.
secure_audit_log
SECURITY DEFINER
Search Path Hijacking vulnerability detected. Function executes with owner privileges without schema locking.
-- REMEDIATION: SECURITY DEFINER Search Path Hijacking
-- Fix: Explicit Search Path & Contextual Validation
CREATE OR REPLACE FUNCTION "internal"."secure_audit_log"(row_id uuid)
RETURNS void
LANGUAGE plpgsql
SECURITY DEFINER -- Runs with owner privileges
SET search_path = public, pg_temp -- Prevent hijacking by locking the search path
AS $$
BEGIN
-- Verify the session JWT 'tenant_id' matches the target row's tenant_id
IF NOT EXISTS (
SELECT 1 FROM public.tenant_data
WHERE id = row_id
AND tenant_id = (select auth.jwt() ->> 'tenant_id')::uuid
) THEN
RAISE EXCEPTION 'Unauthorized: Isolation Boundary Violation Detected';
END IF;
INSERT INTO internal.audit_trail (target_id, actor_id)
VALUES (row_id, auth.uid());
END;
$$;