Skip to main content
Security Guides

Supabase Storage Security: Prevent Public Bucket Data Leaks in 15 Minutes

SecuriSky TeamApril 18, 202615 min read

Securing Supabase Storage

To prevent public bucket data leaks in Supabase, you need to ensure that your storage buckets are properly configured and access-controlled. The main question is: how do you secure your Supabase storage buckets to prevent unauthorized access?

The answer is to use a combination of bucket-level permissions, row-level security (RLS), and storage bucket policies. By default, Supabase storage buckets are publicly accessible, which can lead to data leaks and unauthorized access.

Understanding Supabase Storage Buckets

Supabase storage buckets are used to store and serve files, such as images, videos, and documents. When you create a new bucket, it is publicly accessible by default, which means that anyone can access and download files from the bucket.

To demonstrate this, let's create a new bucket using the Supabase JavaScript library:

import { createClient } from '@supabase/supabase-js';

const supabaseUrl = 'https://your-supabase-instance.supabase.co';

const supabaseKey = 'your-supabase-key';

const supabaseSecret = 'your-supabase-secret';

const supabase = createClient(supabaseUrl, supabaseKey, supabaseSecret);

async function createBucket() {

const { data, error } = await supabase.storage.createBucket('my-bucket', { public: true, }); console.log(data);

}

createBucket();

In this example, we create a new bucket called my-bucket with public access enabled. This means that anyone can access and download files from the bucket.

Configuring Bucket-Level Permissions

To secure your bucket, you need to configure bucket-level permissions. You can do this by updating the bucket's permissions using the Supabase dashboard or the JavaScript library.

Here's an example of how to update the bucket's permissions using the JavaScript library:

async function updateBucketPermissions() {
  const { data, error } = await supabase.storage.updateBucket('my-bucket', {
    public: false,
  });
  console.log(data);

}

updateBucketPermissions();

In this example, we update the my-bucket bucket's permissions to disable public access.

Implementing Row-Level Security (RLS)

Row-level security (RLS) is a feature in Supabase that allows you to control access to specific rows in a table based on the user's role or permissions. You can use RLS to secure your storage buckets by controlling access to the files stored in the bucket.

Here's an example of how to implement RLS for a storage bucket:

import os

from supabase import create_client, Client

url: str = os.environ.get("SUPABASE_URL")

key: str = os.environ.get("SUPABASE_KEY")

secret: str = os.environ.get("SUPABASE_SECRET")

supabase: Client = create_client(url, key, secret)

async def get_file(bucket_id: str, file_id: str, user_id: str):

# Check if the user has permission to access the file { data: file, error } = await supabase.from("files").select("*").eq("id", file_id) if file.user_id == user_id: # Return the file { data: file_data, error } = await supabase.storage.from(bucket_id).download(file_id) return file_data else: # Return an error return {"error": "Access denied"}

In this example, we use RLS to control access to files stored in a bucket. We check if the user has permission to access the file by checking if the user's ID matches the file's user ID.

Storage Bucket Policies

Storage bucket policies are used to define permissions for a bucket. You can use bucket policies to grant or deny access to a bucket based on specific conditions, such as the user's role or IP address.

Here's an example of how to create a bucket policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowGetObject",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*"
    }
  ]

}

In this example, we create a bucket policy that allows the GetObjects action for the my-bucket bucket.

Quick Fix Checklist

  • [ ] Create a new bucket with private access
  • [ ] Update the bucket's permissions to disable public access
  • [ ] Implement row-level security (RLS) to control access to files
  • [ ] Create a bucket policy to define permissions for the bucket
  • [ ] Use a tool like SecuriSky to detect and prevent public bucket data leaks automatically
  • You can also use SecuriSky to scan your app for potential security vulnerabilities and detect public bucket data leaks.

    Try it free

    Scan your app for these issues now

    Paste your URL and get a full security, performance, and SEO report in under 2 minutes — no signup required.

    Run a free scan