QueryProxy
Doküman menüsü

Veri maskeleme

Kolon deseni ve içerik regex maskeleme kuralları, üç strateji ve sonuçların neden diske ulaşmadan önce maskelendiği.

Güncelleme:

Maskeleme kuralları, kişisel verileri geliştiricinin gördüğü sonuç verisinin — ve QueryProxy’nin kendi sonuç depolamasının — dışında tutar. Kurallar DBA’ler tarafından Masking altında yönetilir.

Yazım anında maskeleme

Maskeleme sonuç akışının içinde çalışır: işçi sonuç kümesini cursor ile gezerken her satır, sonuç dosyasına yazılmadan önce maskelenir. Bir sonucun maskesiz hâli diskte hiç var olmaz; dolayısıyla depolanan sonuç verisi sonradan maskesiz görüntülenemez ya da indirilemez. Bilinçli bir tasarım kararı olarak “maskeyi kaldır” düğmesi yoktur.

Hata mesajları

Başarısız bir çalıştırmanın da metni vardır ve bir veritabanı sürücüsü hatası, onu bozan değerleri yankılayabilir (örneğin PostgreSQL’in invalid input syntax for type integer: "[email protected]", MySQL’in Duplicate entry '[email protected]' mesajı ya da SQL’in kendisi). Bu yüzden hata mesajı, saklanmadan ya da gösterilmeden önce sonuç verisiyle aynı yazım anında maskeleme ilkesinden geçer:

  1. Temizleme. Bağlantının kendi parolası, kullanıcı adı, host’u ve veritabanı adı [redacted] ile değiştirilir.
  2. Regex kuralları. Bağlantının etkin her içerik kuralı, eşleştiği yeri kendi stratejisiyle yerinde maskeler. Kuralı olmayan bir bağlantıda yalnızca temizleme uygulanır.
  3. Kolon kuralları, fail-closed. Mesaj, bir kolon kuralının kapsadığı bir kolonu anıyorsa içindeki her literal değer (tırnaklı değerler, Duplicate entry '…', Key (…)=(…)) eşleşen kolon kuralları arasındaki en güçlü stratejiyle (full, sonra hash, sonra partial) maskelenir. Böyle bir mesajda tırnaklar dengeli değilse (MySQL’in doesn't exist mesajındaki gibi başıboş bir kesme işareti eşleşmeyi kaydırır) mesajın tamamı ***** olur. PostgreSQL’in Failing row contains (…) mesajı kolon adı vermez; bağlantıda herhangi bir kural varsa satırın tamamı maskelenir.
  4. Aksi hâlde fail-closed. Bir regex değerlendirilemiyorsa mesajın tamamı ***** olur. Kuralların alınacağı bağlantı kalmadıysa ya da maskeleme kendisi başarısız olduysa saklanan metin sabit Job failed; details in application log. mesajıdır.

Talep detayında, talep sahibinin bildiriminde (ilk 120 karakter) ve denetim günlüğünde görünen budur. Ham mesaj yalnızca uygulama günlüğüne yazılır. Kuyruk işinin kendi hata işleyicisi (failed()) de aynı yolu kullanır; yani normal çalıştırma yolunun dışındaki bir hata artık ham metin saklamaz, talep sahibine tam bir kez bildirim gider ve hata tam bir kez denetlenir.

Neyi kapsamaz. Mesajdaki tırnaksız, çıplak bir değer (örneğin value 42) yalnızca regex kuralıyla yakalanır, kolon kuralıyla yakalanmaz. Hata, SQL’i yazıldığı gibi taşır: metin literal’leri tırnaklıdır, sayılar değildir (WHERE national_id = 12345678901). Hassas biçimler için içerik kurallarını etkin tutun. Bağlantı testi hatalarını ayrı bir yoldan bildirir; bu yolun dışındadır.

Yükseltmeden sonra

Önceki sürümlerin sakladığı mesajlar siz maskeleyene kadar maskesiz kalır. Bir kez çalıştırın:

php artisan queryproxy:mask-error-messages --dry-run   # yalnızca raporlar
php artisan queryproxy:mask-error-messages

Komut, var olan taleplerin hata mesajını ve uygulama içi “talep başarısız” bildirimlerindeki kopyayı her bağlantının güncel kurallarıyla yeniden maskeler. Artık var olmayan bir talep ya da bağlantı sabit mesajı alır. Zaman damgaları ve okundu durumu korunur ve çalıştırma tek bir error_messages.masked denetim kaydı olarak yazılır. Aynı kurallarla yeniden çalıştırmak hiçbir şeyi değiştirmez; kural değişikliğinden sonra güncel kuralları uygular ve yalnızca maske ekler, hiçbir maskeyi kaldırmaz. Yeni mesajlar yazıldıkları anda yürürlükte olan kurallarla maskelenir; bir kuralı değiştirmek saklanan mesajları kendiliğinden yeniden maskelemez. Bağlantı kuralları okunamayan bir kayıt atlanır, değiştirilmez ve raporlanır; komut hata koduyla çıkar.

[!IMPORTANT] Denetim günlüğü değiştirilemez; komut ona dokunamaz. Önceki sürümlerin yazdığı denetim kayıtları (request.execution_failed, execution.late_completion) maskelenmemiş mesaj metnini korur ve bir denetçi bunları hâlâ okuyup dışa aktarabilir. Orada yalnızca yükseltmeden sonraki hatalar maskelenir.

Kural türleri

Eşleme türü Neye bakar Örnek desen
Kolon Kolonun adı (büyük/küçük harf duyarsız joker; | alternatifleri ayırır) *email*, *password*|*secret*|*token*|*api_key*
Regex Hücrenin içeriği (ayraçlı PCRE) /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/

Aynı değer için kolon kuralı içerik kuralından önce gelir. İki tür de her skaler değerde çalışır, yalnızca string’lerde değil: PDO BIGINT ve DECIMAL kolonları için native tamsayılar döndürür; bu yüzden sayı olarak saklanan bir kart numarası ya da kimlik numarası, metin olarak saklananla aynı şekilde içerik kurallarıyla eşleşir. Hiçbir kuralın eşleşmediği değer özgün tipiyle olduğu gibi döndürülür.

Her kural ya takım genelinde geçerlidir ya da tek bir bağlantıya sabitlenir; silmeden açılıp kapatılabilir.

Stratejiler

Strateji Sonuç Örnek
full Değerin tamamı değiştirilir *****
partial İlk ve son karakter korunur, arada en fazla 8 yıldız a***@***.com, 5********2
hash Deterministik SHA-256 öneki sha256:9f86d081884c

partial e-postaları okunur tutar (ilk harf + TLD); üç karakter ya da daha kısa değerler *** olur. hash ise analistlerin değeri görmeden kolon üzerinde join/sayım yapabilmesini sağlar.

Varsayılan kural seti

Tek tıkla (Add default rules) makul varsayılanlar kurulur: e-posta, telefon ve kart kolonları (partial), secret/token/parola/api_key kolonları (full), ayrıca şunlar için içerik regex’leri:

  • e-posta adresleri (partial),
  • kredi kartı numaraları (partial); gerçek issuer identification aralıklarına daraltıldı, böylece artık 13 haneli epoch zaman damgalarında, snowflake id’lerde ya da sipariş numaralarında tetiklenmez,
  • sabit önekli üretici API anahtarları ve token’ları — sk-, xox…, ghp_ ve benzerleri, glpat-, AKIA/ASIA, AIza (full),
  • JSON Web Token’lar (full),
  • PEM formatındaki private key blokları (full),
  • yüksek entropili sırlar: küçük harf, büyük harf ve rakam karışımı 32 ya da daha fazla karakter (full).

Sırlara yönelik içerik kuralları şu yüzden vardır: kolon kuralı yalnızca çıktı kolon adını görür ve o adı sorguyu yazan seçer — SELECT api_key AS k, en katı *api_key* desenini bile atlatıyordu. Değer üzerinden eşleme, takma adla gizlenmiş sırrı yine de yakalar.

Varsayılanlar idempotenttir — iki kez eklemek yeni bir şey oluşturmaz.

Yeni takımlar varsayılan kurallarla başlar; mevcut takımlar bunları otomatik almaz. v0.2.1’den itibaren oluşturulan her takımda — Teams & Users altında, demo tohumuyla ya da başka herhangi bir yolla — varsayılan kurallar oluşturulduğu anda kurulur. Yükseltmeden önce var olan takımlara geriye dönük kurulum yapılmaz ve hiçbir takım yükseltmede yeni eklenen varsayılanları kendiliğinden almaz: böyle her takım için Masking’i açın ve Add default rules’u bir kez çalıştırın. Zaten kuralları olan bir takımda çalıştırmak güvenlidir — yalnızca eksik varsayılanlar eklenir, mevcut hiçbir şey değiştirilmez ya da kaldırılmaz. Bu, bir takımın daha önce kurduğu eski, daha geniş kart deseninin kural listesinde kalması demektir; artık istemiyorsanız onu kapatın.

Etkin hiçbir maskeleme kuralı olmayan bir takım için Query Studio ve Masking sayfalarında bir uyarı banner’ı görünür. Hiç kural yoksa “This team has no masking rules — query results are returned unmasked.” yazar ve Masking sayfasında doğrudan Add default rules’a bağlanır. Kurallar var ama hepsi kapalıysa “This team has no enabled masking rules — query results are returned unmasked.” yazar ve onları etkinleştirmenizi ister. Query Studio’da banner kullanıcıya bir DBA’e sormasını söyler. Denetim takım geneline bakar: tek etkin kuralı bir bağlantıya bağlı olan bir takımda banner görünmez, ama diğer bağlantılarındaki sorgular maskesiz döner — en az bir takım geneli kuralı etkin tutun. Varsayılanlar ya hep ya hiç kurulur, bu yüzden bir takım oluşturulurken yaşanan bir hata onu asla yarım bir kural setiyle bırakmaz.

Kuralları test etmek

Masking sayfasının altındaki playground, etkin kurallarınızın önizlemesini verir: bir kolon adı ve örnek değer girin, sonucun tam olarak nasıl görüneceğini görün. Önizleme takımın etkin kurallarının tamamını uygular; bağlantıya göre filtrelenmez. Geçersiz regex desenleri kayıt anında reddedilir; felaket geri izlemeye (ReDoS) yol açabilecek desenler de reddedilir — bozuk ya da kontrolsüz bir desen üretime girip sessizce hiçbir şeyi eşleştirmeden duramaz.

Regex maskeleme ayrıca kapalı yönde başarısız olur (fail-closed): bir desen çalışma anında bir değere karşı değerlendirilemezse, o değer ham verilmez, maskelenir — maskeleme, en çok korumaya ihtiyaç duyduğu patolojik veride açık kalmaz.

Gezinmek için ok tuşları, açmak için Enter.