// docs / baas security / supabase storage
Supabase storage bucket güvenlik kontrol listesi: 22 madde
Supabase Storage, S3 uyumlu bir bucket'ın etrafındaki ince bir sarmalayıcıdır ve veritabanıyla aynı Row-Level Security modeline sahiptir. Bu, tabloları etkileyen aynı RLS tuzaklarının dosya erişimini de etkilediği anlamına gelir — ve yapay zeka kodlama araçları yüklemeleri bağladığında ortaya çıkan birkaç storage'a özgü tuzak. Bu kontrol listesi beş bölümde 22 madde içerir: bucket yapılandırması, RLS policy'leri, yükleme doğrulama, imzalı URL'ler ve operasyonel hijyen. Her biri 15 dakikadan kısa sürede doğrulanabilir.
Aşağıdaki her madde temeldir. Temel RLS mekanikleri için Supabase RLS tarayıcısı'na bakın. Storage'a komşu anahtar ifşa sınıfı için JavaScript'te ifşa olan Supabase service role anahtarı'na bakın.
Bucket yapılandırması
Doğru varsayılanlarla başlayın. Yanlış yapılandırılmış bir bucket, RLS'iniz doğru olsa da olmasa da dosya sızdırır.
- Her bucket'ı varsayılan olarak private yapın. Supabase Dashboard → Storage → Buckets'ta, açık bir nedeniniz yoksa (pazarlama varlıkları, PII içermeyen public avatarlar) Public bucket geçişini kapatın. Public bucket'lar okuma işlemleri için RLS'i atlar — bucket adına sahip herkes listeleyebilir ve indirebilir.
- Her bucket'ta sert bir dosya boyutu sınırı belirleyin. Dashboard → Bucket settings → File size limit. 50 MB kullanıcı yüklemeleri için makul bir varsayılandır; video / büyük dosya kullanım senaryoları için kasıtlı olarak yükseltin. Sınır olmadan, tek bir kötü niyetli yükleme storage kotanızı veya aylık bant genişliğinizi tüketebilir.
- Her bucket için izin verilen MIME türlerini kısıtlayın. İzin verilen MIME türleri listesi — açık allowlist, blocklist değil. Yalnızca resim içeren bucket'lar için
image/jpeg,image/png,image/webp. Kullanıcı içeriği bucket'ında aslatext/html,application/javascriptveyaimage/svg+xml'a izin vermeyin — imzalı URL üzerinden sunulduklarında tarayıcıda yürütülürler. - Bir paylaşımlı bucket değil, içerik türü başına bir bucket kullanın. Bucket başına ayarlar (boyut, MIME türleri, RLS policy'leri) sahip olduğunuz ayrıntı düzeyidir. Bir
user-avatarsbucket'ı, birdocument-uploadsbucket'ı ve birpublic-assetsbucket'ı, karışık bir bucket'tan kilitlemesi daha kolaydır. - Frontend yüklerse CORS yapılandırmasını doğrulayın. Kullanıcılar doğrudan tarayıcıdan imzalı bir URL'ye yüklüyorsa, bucket CORS üretim origin'inizi listelemelidir.
*yalnızca public bucket'lar için kabul edilebilir — asla kullanıcı PII içeren bucket'lar için değil.
storage.objects üzerinde RLS policy'leri
Supabase Storage dosya meta verilerini storage.objects tablosunda saklar. Bu tablodaki RLS, kimin dosya okuyabileceğini, yükleyebileceğini, güncelleyebileceğini veya silebileceğini kontrol eder. RLS olmadan, bucket'ın public/private bayrağı tek korumanızdır.
- storage.objects üzerinde RLS'in etkin olduğunu teyit edin.
SELECT rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects';truedöndürmelidir. Supabase yeni projelerde varsayılan olarak etkinleştirir; devre dışı bırakılmadığını doğrulayın. - Private bucket'lar için
auth.uid()'ye kapsamlanmış bir SELECT policy'si yazın.CREATE POLICY "users_read_own_files" ON storage.objects FOR SELECT USING (auth.uid()::text = (storage.foldername(name))[1]);. Konvansiyon, dosyaları[user-id]/[filename]altında saklamak ve sahibi yoldan çıkarmak içinstorage.foldername()kullanmaktır. - Aynı yol konvansiyonunu zorlayan bir INSERT policy'si yazın.
CREATE POLICY "users_upload_own" ON storage.objects FOR INSERT WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);. WITH CHECK olmadan, kimliği doğrulanmış bir kullanıcı başka bir kullanıcının klasörüne yükleyebilir. - Uygulamanız dosya düzenlemelerini veya silmelerini destekliyorsa UPDATE ve DELETE policy'leri ekleyin. Her komutun kendi policy'sine ihtiyacı vardır. DELETE'i atlamak, kimliği doğrulanmış kullanıcıların kendi dosyalarını kaldıramaması demektir; UPDATE'i atlamak dosya üzerine yazmaların sessizce başarısız olması demektir.
- İki tarayıcı oturumunda kullanıcılar arası erişimi test edin. Kullanıcı A olarak oturum açın, bir dosya yükleyin, yolu kopyalayın. Başka bir tarayıcıda Kullanıcı B olarak oturum açın, dosyayı REST API üzerinden almayı deneyin. Yanıt
403veya404olmalı, asla200olmamalıdır.
-- Confirm RLS on storage.objects
SELECT rowsecurity
FROM pg_tables
WHERE schemaname = 'storage' AND tablename = 'objects';
-- SELECT policy: scope reads to the owning user's folder.
CREATE POLICY "users_read_own_files"
ON storage.objects
FOR SELECT
USING (auth.uid()::text = (storage.foldername(name))[1]);
-- INSERT policy: enforce the [user-id]/[filename] path convention.
CREATE POLICY "users_upload_own"
ON storage.objects
FOR INSERT
WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);Yükleme doğrulama
Bucket'ta MIME ve boyut kısıtlamaları olsa bile her yüklemeyi sunucu tarafında doğrulayın. Yapay zeka kodlama araçları varsayılan olarak yalnızca istemci doğrulaması üretir; bu hiçbir şeyi korumaz.
- MIME türünü
Content-Typebaşlığından değil, dosyanın gerçek baytlarından sunucu tarafında yeniden kontrol edin.file-type(Node) gibi bir kütüphane veya magic-byte sniffing kullanın. Bir saldırgan, aslında poliglot HTML / JavaScript yükü olan bir dosyadaContent-Type: image/jpegiddia edebilir. - Yüklenen resimlerden EXIF meta verisini soyun. EXIF GPS koordinatları, cihaz seri numaraları ve zaman damgaları içerebilir. Storage'dan önce soymak için
.withMetadata(false)ilesharpveyaexif-parserkullanın. scriptetiketleri veyaonloadişleyicileri içeren SVG'leri reddedin. SVG XML'dir — ve birçok yapay zeka tarafından üretilmiş uygulama SVG yüklemelerine "sadece bir resim" olarak izin verir. Sunucu tarafındaDOMPurifykullanın veya SVG yüklemelerini tamamen reddedin.- Belirlenebilir ama tahmin edilemez dosya adları kullanın. Orijinal dosya adını korumayın. Bir UUID veya dosya içeriğinin bir hash'ini kullanın. Orijinal dosya adları sızıntı yapar ("
passport_scan_2024_01_15.jpg") ve tahmin edilebilir adlar sıralamayı mümkün kılar.
İmzalı URL'ler
İmzalı URL'ler, istemcilerin private bucket'lara nasıl eriştiğidir. Sona erme süresi, bucket kapsamı ve neyin loglandığı önemlidir.
- İmzalı URL son kullanma tarihini varsayılan olarak 1 saat veya daha az yapın. Supabase JS SDK'sının
createSignedUrl(path, expiresIn)saniye alır.31536000(bir yıl) gibi değerleri asla kullanmayın — URL kalıcı yarı-public bir bağlantı olur. - İmzalı URL'leri asla veritabanınızda saklamayın. Her istekte sunucu tarafında taze olanlar oluşturun. Veritabanı dökümü yoluyla sızan 1 yıllık son kullanma tarihine sahip saklanmış bir imzalı URL, uzun vadeli erişim verir.
- Sadece dosya yüklemelerini değil, imzalı URL oluşturmayı da loglayın. Daha sonra bir tehlikeden şüphelenirseniz, hangi URL'yi kimin ne zaman oluşturduğunu bilmeniz gerekir.
auth.uid()+ bucket + nesne yolu + zaman damgasını loglayın. - Kullanıcı tarafından yüklenen dosyaları sunarken
downloadAsseçeneğini kullanın.createSignedUrl(path, expiresIn, { download: '.jpg' }), render etmek yerine dosyanın indirilmesi içinContent-Disposition: attachmentbaşlığını zorlar — HTML / SVG / PDF içinde HTML yürütme sınıfını yener.
Operasyonel hijyen
Storage yapılandırması zamanla kayar. Bu dört operasyonel madde yüzeyi sıkı tutar.
- Bucket'ları üç ayda bir denetleyin. Dashboard → Storage → Buckets. Public/private durumu ve MIME türü listelerinin uygulamanın beklediği şekilde olduğunu teyit edin. "Geçici olarak" oluşturulan bucket'lar, kimse kaldırmazsa kalıcı hale gelir.
- Anonim list işlemlerini izleyin. Storage logları (Dashboard → Logs → Storage)
LISTisteklerini kaydeder. Private bir bucket'a karşı anonim list isteklerinin yükselmesi, birinin dışarıdan onu sondaladığı anlamına gelir. - Geçici yüklemeler için bir saklama policy'si belirleyin. Geçici bucket'lar (resim önizleme, taslak yüklemeler), zamanlanmış bir fonksiyon aracılığıyla 24-72 saat sonra otomatik silinmelidir. Belirsiz saklama, GDPR / CCPA veri minimizasyonu yükümlülükleri altında bir sorumluluktur.
- Aylık bir FixVibe taraması çalıştırın.
baas.supabase-storage-publickontrolü, anonimGET+LIST'e yanıt veren bucket'lar için sondalar gönderir. Yeni bucket'lar eklenir; eski olanlar görünürlüğü değiştirir — sadece sürekli tarama kaymayı yakalar.
Sonraki adımlar
Üretim URL'nize karşı bir FixVibe taraması çalıştırın — anonim storage listelemeleri baas.supabase-storage-public altında görünür. Bu kontrol listesini tablo katmanı için Supabase RLS tarayıcısı ve anahtar ifşa komşuluğu için JavaScript'te ifşa olan Supabase service role anahtarı ile eşleştirin. Diğer BaaS sağlayıcılarındaki storage yanlış yapılandırmaları için BaaS yanlış yapılandırma tarayıcısı bölümüne bakın.
