Aikido

SQL’de SELECT * kullanımından kaçınma: veri sızıntılarını önleme

Performans

Kural
Kaçınılması gerekenler SELECT * içinde SQL sorgularında *'yi kullanmayın.
SELECT * içinde üretim kodunda uygulamaları uygulamaları
kırılgan şemaya şema değişikliklere ve gizler verilerin bağımlılıklarını gizler.

Desteklenen diller: 45+

Giriş

Kullanım SELECT * Üretim ortamındaki sorgular, uygulamanızın kullanmadığı sütunlar da dahil olmak üzere bir tablodaki tüm sütunları alır. Veritabanı şemaları değişip yeni sütunlar eklendiğinde (şifreler veya kişisel kimlik bilgileri gibi hassas veriler dahil), SELECT * kod değişikliği yapmadan otomatik olarak bunları almaya başlar. Bu durum güvenlik açıklarına yol açar ve uygulama mantığınızdaki varsayımları bozar.

Neden önemli?

Performans üzerindeki etkisi: Gereksiz sütunların alınması, sorgu yürütme süresini, ağ aktarım boyutunu ve bellek tüketimini artırır. Aslında sadece 5 sütuna ihtiyacınız varken 50 sütun içeren bir tablo, gereğinden 10 kat daha fazla veri aktardığınız anlamına gelir; bu da yanıt sürelerini uzatır ve altyapı maliyetlerini artırır.

Güvenlikle ilgili hususlar: Tablolara eklenen yeni sütunlar (denetim alanları, dahili işaretleyiciler, hassas kullanıcı verileri) otomatik olarak şu yol üzerinden erişime açılır: SELECT * sorgular. API’niz, o uç nokta için asla amaçlanmamış şifre karma değerlerini, sosyal güvenlik numaralarını veya şirket içi verileri sızdırmaya başlayabilir.

Kodun bakım kolaylığı: Ne zaman SELECT * Şema değişikliklerinin ardından sorgular çalışmaz hale gelir; bu hata derleme aşamasında değil, çalışma zamanında ortaya çıkar. Null değeri kabul etmeyen yeni bir sütun veya yeniden adlandırılmış bir alan, üretim ortamında hatalara neden olur. Açıkça belirtilen sütun listeleri, bağımlılıkları netleştirir ve şemalar uyumsuz şekilde değiştiğinde derleme işlemlerini durdurur.

Kod örnekleri

❌ Uygun değil:

async function getUserProfile(userId) {
    const query = 'SELECT * FROM users WHERE id = ?';
    const [user] = await db.execute(query, [userId]);

    return {
        name: user.name,
        email: user.email,
        createdAt: user.created_at
    };
}

Neden yanlış: Bu sorgu, password_hash, ssn, internal_notes veya deleted_at gibi potansiyel olarak hassas alanlar da dahil olmak üzere tüm sütunları getirir. Şema büyüdükçe bu sorgu yavaşlar ve daha fazla veriyi açığa çıkarır; oysa uygulama sadece üç alanı kullanmaktadır.

✅ Uygunluk:

async function getUserProfile(userId) {
    const query = `
        SELECT name, email, created_at
        FROM users
        WHERE id = ?
    `;
    const [user] = await db.execute(query, [userId]);

    return {
        name: user.name,
        email: user.email,
        createdAt: user.created_at
    };
}

Sonuç

SQL sorgularında her zaman açıkça sütun listeleri belirtin. Bu, veri sızıntılarını önler, performansı artırır ve kod ile şema arasındaki bağımlılıkları netleştirir. Sütun adlarını yazmanın getirdiği küçük bir ön maliyet, güvenlik ve performans sorunlarının tüm türlerini önler.

Sık Sorulan Sorular

Sorularınız mı var?

SELECT * ne zaman kabul edilebilir?

Yalnızca geliştirme veya hata ayıklama aşamasındaki geçici sorgularda kullanın; üretim kodunda asla kullanmayın. Tüm sütunlara gerçekten ihtiyaç duyduğunuz veri taşıma komut dosyaları veya tek seferlik raporlar için SELECT * kullanımı makul olabilir. Uygulama kodunda ise, şu anda tüm sütunlara ihtiyacınız olsa bile her zaman açıkça belirtilen sütun listelerini kullanın; çünkü şema değişiklikleri kaçınılmazdır.

Peki ya SELECT * sorguları oluşturan ORM’ler ne olacak?

Configure your ORM to select specific fields. Most ORMs (Sequelize, TypeORM, Prisma, SQLAlchemy) support field selection: User.findOne({ attributes: ['name', 'email'] }) or prisma.user.findUnique({ select: { name: true, email: true } }). Always use these options to control what data is retrieved.

SELECT * komutu veritabanı performansını önemli ölçüde etkiler mi?

Evet, özellikle geniş tablolar söz konusu olduğunda. Veritabanları diskten daha fazla sayfa okumak zorunda kalır, dizinler yeterince etkili bir şekilde kullanılamaz ve sorgu sonuç kümeleri veritabanı tampon havuzunda daha fazla bellek tüketir. Ağ aktarım süresi, veri boyutuyla orantılı olarak artar. TEXT veya BLOB sütunları içeren tablolarda bu durumun etkisi ciddi boyutlara ulaşabilir.

Çoğu sütuna ihtiyacım olan sorguları nasıl işleyebilirim?

Bunları açıkça listeleyin. Sütun listesini oluşturmak için IDE’nizin otomatik tamamlama özelliğini kullanın veya `information_schema`’yı sorgulayın. Bazı ekipler, her bir kullanım senaryosu için tam olarak gerekli olan sütunları tanımlayan görünüm nesneleri oluşturur veya veritabanı görünümlerini kullanır. Açık listelerin sağladığı netlik ve güvenlik, bu durumun getirdiği küçük bir rahatsızlığı telafi eder.

Kod tabanımda SELECT * ifadelerini nasıl tespit edebilirim?

Kod tabanınızda SELECT * kalıbını (büyük/küçük harf duyarlı olmayan) arayın. Birçok statik analiz aracı ve veritabanı sorgu analizcisi bu tür kalıpları işaretleyebilir. Kod incelemesi sırasında, uygulama kodunda SELECT * içeren tüm PR’leri reddedin. Bazı ekipler, bu kalıpları otomatik olarak tespit etmek ve engellemek için pre-commit hook’ları veya CI kontrollerini kullanır.

Şimdi güvenliğinizi sağlayın

Kodunuzu, bulutunuzu ve çalışma zamanınızı tek bir merkezi sistemde güvenceye alın.
Güvenlik açıklarını otomatik olarak hızla bulun ve düzeltin.

Kredi kartı gerekmez | Tarama sonuçları 32 saniyede.