Bilgi güvenliği ekipleri ve uygulama incelemecileri için

Peel’de güvenlik

Kısacası: board içeriği tarayıcıda, link parçasında (fragment) duran bir anahtarla şifrelenir; sunucularımız okuyamadıkları şifreli veriyi saklar ve iletir. Tam olarak nasıl yaptığımızı ve sınırların nerede olduğunu aşağıda bulabilirsin.

Özet

  • Kart metinleri, isimler, board başlıkları, oylar ve etiketler tarayıcıda üretilen bir board anahtarıyla AES-256-GCM kullanılarak şifrelenir. Anahtar URL parçasında (#k=) taşınır ve hiçbir sunucuya gönderilmez.
  • Kolaylaştırıcı işlemleri, board başlığı (header) ve anlık görüntüler kolaylaştırıcının Ed25519 anahtarıyla imzalanır. Board kimliği bu anahtardan türetildiği için istemciler anahtar değişimini fark eder.
  • Gizli kartlar açılışa kadar kolaylaştırıcıya mühürlenir (X25519 mühürlü kutu) ve tuzlu taahhütlerle (commitment) bağlanır; açılan metin değiştirilemez.
  • Varsayılan olarak anonim: işlemlerde yazar kimliği yoktur; oylar ve tepkiler board’a özel rastgele bir kimlik kullanır.
  • Katılımcılar hiçbir zaman kimlik doğrulamaz. Analitik SDK’sı, reklam veya üçüncü taraf betiği yok; tek istisna ödeme sayfasındaki Paddle.js.
  • Yalnızca Cloudflare. Sahiplenilmemiş board’lar son ziyaretten 60 gün sonra silinir.

Veri nasıl akar

Bir URL’nin parçası (# işaretinden sonraki her şey) tarayıcı tarafından işlenir ve HTTP isteğine dahil edilmez. Peel board anahtarını oraya koyar.

Veri akışı: anahtar linkten yerel olarak okunur; ağdan yalnızca şifreli veri ve asgari meta veri geçer.

Tehdit modeli

Tamamen ele geçirilmiş ya da meraklı bir sunucunun (biz dahil) bir ekibin ne konuştuğuna dair olabildiğince az şey öğrenmesi için tasarlıyoruz.

Neyi koruyoruz

  • Kart metinleri, GIF seçimleri ve isimli modda yazarın adı.
  • Katılımcı isimleri ve avatarları, board adı ve özel şablon başlıkları.
  • Kimin neye oy verdiği ya da tepki gösterdiği ve hangi kartı kimin yazdığı.
  • Retronun bütünlüğü: aşamalar, açılışlar ve kolaylaştırıcı kararları taklit edilemez.

Dikkate aldığımız saldırganlar

  • Kendi sunucularımız, kötü niyetli bir içeriden kişi ya da depolamamıza sızan biri: eline şifreli veri ve meta veri geçer.
  • Ağdaki bir saldırgan: her yerde TLS var; anahtar ağdan hiç geçmez.
  • Anahtarları değiştiren bir sunucu: board kimliği kolaylaştırıcının açık anahtarından türetilir ve istemciler imzalı başlığı doğrular.
  • Gizlice bakmak ya da sahtecilik yapmak isteyen bir katılımcı: gizli kartlar kolaylaştırıcıya mühürlüdür; kolaylaştırıcı işlemleri kolaylaştırıcının imzasını, kart düzenlemeleri kartın anahtarını gerektirir.
  • Çevrimdışı bir yazar adına kartı yeniden yayımlayan kolaylaştırıcı: taahhütler metni değiştirmesini engeller.

Kapsam dışı olanlar, açıkça

  • Katılımcı linkine sahip olan herkes board’u okuyabilir. Erişim kontrolü linkin kendisidir. Linki board’un kendisini paylaşır gibi paylaş.
  • Ele geçirilmiş bir cihaz, kötü niyetli bir tarayıcı eklentisi ya da omzunun üstünden bakan biri.
  • Trafik analizi: sunucu zamanlamayı, boyutları ve sayıları görür (veri haritasına bak).
  • Sunucu kaynaklı hizmet engelleme: mesajları düşürebilir ya da geciktirebilir ama okuyamaz, taklit edemez.

Kriptografi

Tüm kriptografik yapı taşları tarayıcının WebCrypto API’sinden gelir. Özel yapım kriptografi ya da üçüncü taraf kripto kütüphanesi yok.

AnahtarAlgoritmaKullanım
K_boardAES-256-GCM, 96 bit rastgele IVHer işlemi, anlık görüntüyü ve varlık (presence) güncellemesini şifreler. Ek veri (AAD) board kimliğini, işlem türünü ve işlem kimliğini bağlar; böylece şifreli veri başka bir board’a ya da yere tekrar oynatılamaz. Yalnızca link parçasında, #k= içinde yaşar.
K_ownerEd25519Kolaylaştırıcının yetkisi. Kolaylaştırıcı işlemlerini (aşama, zamanlayıcı, spot ışığı, şablon, ayarlar, oylamayı açma, kart gizleme), board başlığını ve anlık görüntüleri imzalar. Sürekli artan bir sayaç tekrar oynatmayı engeller. Yalnızca kolaylaştırıcı linkinde bulunur (&o=).
Board kimliğiSHA-256, ilk 80 bit, base32Kolaylaştırıcının açık anahtarından türetilir; kimliğin kendisi board’un hangi anahtara ait olduğunu kanıtlar. Anahtarı kimliğe uymayan bir başlığı istemciler reddeder.
K_facX25519 mühürlü kutu: geçici X25519 + HKDF-SHA256 + AES-256-GCMYazma sırasında gizli kartlar kolaylaştırıcının açık anahtarına mühürlenir. Onları yalnızca kolaylaştırıcı linki (&f=) açabilir.
Kart anahtarlarıEd25519, kart başına bir anahtarYalnızca yazarda durur. Düzenlemeler ve açılış bu anahtarla imzalanır: kimlik olmadan özgünlük.
Taahhütler128 bit rastgele tuzla HMAC-SHA256Gizli bir kart, içeriğine dair bir taahhüt yayımlar. Açılışta içerik ve tuz yayımlanır, her istemci kontrol eder; kimse metni değiştiremez.
Varlık bilgisiK_board ile AES-256-GCMİsimler, avatarlar ve yazıyor göstergeleri de diğer her şey gibi şifrelenir.
Anahtar paketiPasskey PRF’den ya da kurtarma kodundan HKDF-SHA256, AES-256-GCMGiriş yapan kolaylaştırıcılar board anahtarlarını cihazlar arasında eşitleyebilir. Paket cihazda şifrelenir; sunucu yalnızca şifreli veriyi ve sarılmış anahtarları saklar.

İmzalanan mesajlar alan ayrımlıdır (ör. peel/sig/v1, peel/header/v1, peel/snap/v1); bir amaç için atılan imza başka bir amaçla kullanılamaz.

Gizli kartlar ve açılış

  1. Yazma sırasında yazarın tarayıcısı kartı kolaylaştırıcının X25519 anahtarına mühürler ve tuzlu bir taahhüt yayımlar. Düz metin yazarın cihazında kalır.
  2. Diğer katılımcılar gizli bir kart görür: onu çözemezler, sunucu da çözemez.
  3. Kolaylaştırıcının tarayıcısı mühürlü kartları açabilir (“👁 sadece sen” önizlemesi).
  4. Açılışta her yazar kartını K_board ile şifreleyip kart anahtarıyla imzalayarak, tuzla birlikte yeniden yayımlar.
  5. Yazar çevrimdışıysa kolaylaştırıcı onun adına yayımlar. Her istemci taahhüdü kontrol eder; metin yazarın yazdığıyla aynı olmak zorundadır.

Kolaylaştırıcı teknik olarak önizleyebildiği için, kartlar gizliyken her board’da herkese “kolaylaştırıcı önizleyebilir” etiketi gösterilir. Bu, gizlenebilen bir ayar değildir.

Anonimlik

  • İşlemlerde yazar kimliği yoktur. Sunucu bir kartı bir kişiyle ilişkilendiremez; varsayılan olarak kolaylaştırıcı da ilişkilendiremez.
  • Oylar ve tepkiler, bir isme bağlı olmayan, board’a özel rastgele bir kimlikle tutulur.
  • Yazıyor göstergeleri birinin yazdığını gösterir; ne yazdığını asla.
  • İsimli mod, board’da açıkça seçilen bir ayardır; bu durumda yazarın adı şifreli kartın içinde taşınır.
  • Katılımcılar hiç giriş yapmaz; ilişkilendirilecek bir hesap yoktur.

Veri haritası

Elimizde tuttuğumuz her şey; nerede durduğu, kimin okuyabildiği ve ne kadar kaldığı.

VeriNeredeKim okuyabilirSaklama
Kartlar, oylar, tepkiler, etiketler, aksiyonlar, board adı, özel şablon başlıklarıDurable Object depolaması, şifreliBoard linkine sahip olanlarBoard silinene kadar
İşlem zarfı: tür, sunucu sırası ve zamanı, boyut, kolaylaştırıcı sayacıDurable Object depolamasıPeelBoard silinene kadar
Katılımcı isimleri, avatarlar, yazıyor bilgisiŞifreli olarak iletilir; bağlıyken bellekte tutulurBoard linkine sahip olanlarBağlı kaldığın sürece
Board durumu: aşama, katılımcı ve kart sayıları, katalog şablon kimliği, kilit bilgisi, oluşturma ve silinme zamanlarıDurable Object, D1; kuruluysa Slack/Teams mesajlarıPeel; Slack/Teams kanalınBoard’un ömrü boyunca
Kolaylaştırıcı hesabı: sağlayıcı kimliği, ad, paylaşıldıysa e-posta, bağlı sağlayıcılar, oluşturma tarihi, oturumD1PeelHesabı silene kadar
Anahtar paketi ve sarılmış anahtarlarD1, şifreliYalnızca sen (passkey veya kurtarma kodu)Hesabı silene kadar
Plan, abonelik durumu, Paddle müşteri ve abonelik kimlikleriD1; PaddlePeel, PaddleVergi mevzuatının gerektirdiği süre
Slack/Teams çalışma alanı, kanal ve mesaj kimlikleri; bot token’ı (AES-GCM ile şifreli)D1PeelUygulama kaldırılana kadar
IP adresiCloudflare ağ kenarı, geçici olarak (iletim, hız limitleri)Cloudflare, Peel’in hız sınırlayıcısıVeritabanlarımızda saklanmaz
Günlük sayaçlar (oluşturulan board’lar, ulaşılan aşamalar)D1PeelYalnızca toplu, tanımlayıcı yok

Sunucumuz neyi yapabilir, neyi yapamaz

Yapabilir

  • İşlem türlerini, boyutları, zamanlamayı, aşamayı, katılımcı ve kart sayılarını, katalog şablon kimliğini ve kilit bilgisini görebilir.
  • İşlemleri düşürebilir, geciktirebilir ya da iletmeyi reddedebilir (hizmet engelleme).
  • Ağ kenarında IP adreslerini görebilir.
  • Board’ları ve ulaşılan aşamaları toplu olarak sayabilir.
  • Bir board’u silebilir (süre dolumu, kötüye kullanım bildirimleri).

Yapamaz

  • Kart metinlerini, isimleri, board başlıklarını, özel şablon başlıklarını, oyları ya da etiketleri okuyamaz.
  • Gizli kartları açılıştan önce okuyamaz (sonra da okuyamaz).
  • Kolaylaştırıcı işlemlerini taklit edemez: kolaylaştırıcının imzası gerekir.
  • Kendi anahtarlarını araya sokamaz: board kimliği bunu ele verir.
  • Açılan bir kartın metnini değiştiremez: taahhütler ve kart imzaları bunu ele verir.
  • Hangi kartı kimin yazdığını bilemez.

Her web uygulamasında olduğu gibi, sunduğumuz koda güvenirsin. Bu yüzeyi küçük tutuyoruz: sıkı bir İçerik Güvenliği Politikası, yalnızca kendi kaynağımıza izin veren script-src, üçüncü taraf betiği yok; protokol talep üzerine incelemeye açık.

Slack ve Microsoft Teams

  • Mesajlar board linkini ve meta veriyi (başlık, aşama, sayılar) taşır. Kart metni yalnızca kolaylaştırıcı bir özet paylaşıp onayladığında gönderilir.
  • Katılım kartı, anahtarı da içeren katılımcı linkini taşır. O kanalı okuyabilen herkes katılabilir; tıpkı linki oraya yapıştırmak gibi.
  • Link önizlemeleri yalnızca aşamayı ve sayıları gösterir, içeriği asla.
  • Slack izinleri: commands, chat:write, links:read, links:write; users:read yalnızca ekip etiketlemeyi açarsa.
  • Bot token’ları durağan hâlde şifrelidir (AES-GCM, anahtar Worker gizli değişkeninde). Slack istek imzaları ve Bot Framework token’ları her istekte doğrulanır.
  • Uygulamayı kaldırmak tüm gönderimleri durdurur ve token’larını siler.

Web ve altyapı

  • Yalnızca Cloudflare: 1801 Labs hesabında Pages, Workers, Durable Objects, D1, R2 ve KV. Başka sunucu yok.
  • Her yerde TLS, HSTS ve sıkı bir İçerik Güvenliği Politikası.
  • Analitik SDK’sı yok, reklam yok, üçüncü taraf betiği yok. Tek istisna yalnızca ödeme sayfasında yüklenen Paddle.js.
  • Tek çerez, yalnızca giriş yapan kolaylaştırıcılar için: peel_session, httpOnly, Secure, SameSite=Lax.
  • GIF araması ve medya API’miz üzerinden geçer; katılımcıların IP adresleri GIPHY’ye hiç ulaşmaz.
  • Fontlar ve dosyalar kendi sunucumuzda. CDN fontu yok, takip pikseli yok.
  • IP ve board başına hız limitleri; kötüye kullanım bildirimi ve kolaylaştırıcı kilidi.

Hesaplar ve saklama

  • Katılımcılar hiçbir zaman kimlik doğrulamaz. Kolaylaştırıcılar yalnızca board’ları saklamak ya da ücretli özellikleri kullanmak için Google (Teams üzerinden Entra ID) ile giriş yapar.
  • Bir hesap; bir kimlik, sağlayıcıdan gelen ad ve e-posta ile bir passkey (WebAuthn PRF) ya da kurtarma koduyla açılan şifreli bir anahtar paketi saklar. Giriş yapmak sahiplik verir, içeriğe erişim değil.
  • Bir board’u sahiplenmek, kolaylaştırıcı imzasıyla kanıtlanır. Board anahtarları asla gönderilmez.
  • Hesapsız board’lar son ziyaretten 60 gün sonra silinir; her ziyaret süreyi sıfırlar. Depolamayı Durable Object alarmları siler.
  • Hesabını silmek oturumları, anahtar paketini ve kütüphaneni siler; board’larına 60 günlük süreyi geri verir.

Sorumlu bildirim

Bir şey mi buldun? Önce bize söyle, birlikte çalışalım. Bildirimleri üç iş günü içinde yanıtlıyoruz.

[email protected]

  • Kamuya açıklamadan önce düzeltmemiz için makul bir süre tanı (hedefimiz 90 gün).
  • Kendi board’ların ve hesaplarınla test et. Başkalarının verilerine erişme, hizmeti aksatma.
  • Bu kurallara uyan iyi niyetli araştırmalar için hukuki yola başvurmayız.
  • Makinece okunabilir iletişim: /.well-known/security.txt.

Şirket planı müşterileri bir güvenlik inceleme paketi alır (anket cevapları, alt veri işleyenler, veri akışları). DPA · Gizlilik