1 puan yazan GN⁺ 2024-09-13 | 1 yorum | WhatsApp'ta paylaş
  • Mobil flört uygulaması Feeld'in arka ucunun incelenmesi sırasında profil ifşası, mesaj okuma·değiştirme ve sohbet eklerine erişim dahil 8 güvenlik açığı bulundu; ilki dışında kalanların tamamı OWASP Top 10'daki Broken Access Control kapsamına giriyor
  • Normal kullanıcılar uygulama ekranında yalnızca sınırlı bilgi görse de, bir proxy ile yanıtlar incelendiğinde ‘beğeni’ gönderen kullanıcıların yaşı, mesafesi, profil fotoğrafı ve streamUserId gibi premium düzeyde bilgiler alınabiliyordu
  • Birden fazla açık, streamUserId, profileId, messageId ve channelID gibi tanımlayıcıların başka API yanıtlarından alınıp istek parametrelerine eklenmesiyle zincirlenebildi ve böylece başkalarının mesajlarına, eşleşmelerine, profillerine, beğenilerine ve sohbet gönderimlerine erişim kapsamı genişledi
  • Sohbet eklerinde normal fotoğraf, 5~15 saniyelik sınırlı fotoğraf, normal video ve tek seferlik oynatılan video türlerinin tamamında sorun doğrulandı; bazı Cloudinary ve Stream CDN URL'lerine kimlik doğrulaması olmadan erişilebildi
  • FORTBRIDGE, 8 Mart 2024'te sorunları Feeld'e bildirdi; Feeld birkaç kez yayının ertelenmesini istedi ve 16 Ağustos 2024'te kalan maddeleri hafifletmek için değişiklikler uyguladığını bildirdi; blog yazısı ise 10 Eylül 2024'te yayımlandı

Feeld'de doğrulanan açıkların kapsamı

  • Hedef, Tinder ve Bumble'a benzer bir mobil flört uygulaması olan Feeld; uygulama mesafe, yaş, cinsiyet, çift ve konum ölçütlerine göre filtreleme sunuyor
  • Premium kullanıcılar ayrıca kink türü, threesome/group senaryosu ve ilgilenilen ilişki türüne göre de arama yapabiliyor
  • Güvenlik incelemesinde doğrulanan açık sayısı 8
    • Premium olmayan kullanıcılara profil bilgilerinin ifşası
    • Başkalarının mesajlarını okuma
    • Sohbet fotoğrafı ve video eklerine kimlik doğrulaması olmadan erişim
    • Başkalarının mesajlarını silme·geri yükleme·düzenleme
    • Başkalarının profil bilgilerini güncelleme
    • Rastgele kullanıcı profilleri adına ‘Like’ alma
    • Başkalarının sohbetlerine mesaj gönderme
    • Başkalarının eşleşmelerini görüntüleme
  • İlk açık dışında kalanların tamamı OWASP Top 10'daki Broken Access Control kategorisine giriyor

Premium olmayan kullanıcılara ifşa olan profil bilgileri

  • Normal bir kullanıcı, uygulamadaki Likes menüsünde kendisini beğenen kullanıcıları gördüğünde yalnızca ad ve bulanık bir fotoğraf benzeri kısıtlı bilgiler gösteriliyor
  • Burp gibi bir proxy aracıyla istek ve yanıtlar yakalandığında, yanıtta premium kullanıcılarla aynı düzeyde bilgiler yer alıyordu
    • yaş
    • mesafe
    • tam profil fotoğrafı
    • streamUserId
  • Profil fotoğrafları res.cloudinary.com üzerinde depolanıyordu ve kimlik doğrulaması olmadan erişilebiliyordu
  • Yanitdan elde edilen streamUserId, daha sonra başkalarının mesajlarını okuma açığında kullanılabiliyordu

Mesaj ve eşleşme erişim kontrolü sorunları

  • Başkalarının mesajlarını okumak için kurbanın streamUserId değeri gerekiyor ve bu değer çeşitli API isteklerinde açığa çıkıyor
  • Örnek akışta, DiscoverProfiles GraphQL isteğinin yanıtından hedef kullanıcının streamUserId değeri alındıktan sonra, sohbet kanalı isteğindeki member koşuluna bu değer yerleştiriliyor
  • Yanıtta "text" aranarak kurbanın gönderdiği ve aldığı mesajların sayısı ile içerikleri görülebiliyordu
  • Aynı erişim yöntemiyle her mesaja bağlı messageId de elde edilebiliyor, bu değer mesaj silme·geri yükleme·düzenleme işlemlerinde kullanılıyordu
  • ChatListQuery içindeki zayıf profileId parametresi değiştirilerek başka kullanıcıların eşleşmeleri görülebiliyordu
    • Görülebilen bilgiler arasında imaginaryName, yaş, fotoğraf, cinsiyet, sexuality, status ve doğum tarihi bulunuyordu

Sohbet eklerine kimlik doğrulaması olmadan erişim

  • Sohbette paylaşılan ekler fotoğraf ve video olarak ayrılıyor
    • Fotoğraflar, normal görüntülenebilen fotoğraflar veya 5~15 saniyelik sınırlı fotoğraflar olabiliyor
    • Videolar ise normal oynatılabilen videolar veya tek seferlik oynatılan videolar olabiliyor
  • Normal fotoğraflar Feeld uygulamasından api.cloudinary.com adresine yükleniyor ve yanıt olarak photo_id dönüyor
    • Daha sonra fotoğraf feeld.co üzerine kopyalanıp kimliği doğrulanmış kullanıcılara sunuluyor
    • cdn/chat-attachment/<receiver_profileId>/<photo_id> veya <sender_profileId>/<photo_id> biçimindeki yollar kullanılıyor
    • Yoldaki profileId kısmı en az 1 karakterlik rastgele bir dizeye kısaltılsa bile kimliği doğrulanmış kullanıcılara fotoğraf döndürülüyordu
    • Başına /v1/ eklenen yol, Cloudinary'de depolanan orijinal fotoğrafın URL'sini döndürüyor ve bu URL'ye kimlik doğrulaması olmadan erişilebiliyordu
  • Süre sınırlı fotoğraflar yüklenirken visibilityMilliseconds:15000 gibi ek parametreler kullanılıyor
    • Alıcıya ait endpoint, erişimden 5~15 saniye sonra fotoğrafı siliyor ve artık erişim vermiyor
    • Yükleyenin profileId değeriyle kullanılan endpoint ise 5~15 saniye sonrasında da kimliği doğrulanmış kullanıcılara fotoğrafı vermeye devam ediyordu
    • /v1/ yolu Cloudinary URL'sini döndürüyor ve bu URL'ye kimlik doğrulaması olmadan erişilebiliyordu
  • Videolarda, hem normal videoların hem de tek seferlik videoların URL'leri sohbet mesajlarının içinde yer alıyordu
    • Normal videolar us-east.stream-io-cdn.com üzerine yükleniyordu
    • Tek seferlik videolarda chat.stream-io-api.com tarafındaki yükleme akışı kullanılıyordu
    • Saldırgan, önceki mesaj okuma açığıyla URL'yi elde edip u0026 değerini & ile değiştirirse videoyu kimlik doğrulaması olmadan izleyebiliyordu
  • Tek seferlik videolar saldırgan için yeniden oynatılabiliyordu, ancak alıcının uygulamasında bir kez izlendiğinde video expired olarak gösteriliyordu

Mesaj manipülasyonu, profil değiştirme ve beğeni sahteciliği

  • chat.stream-io-api.com/messages/<messageId> endpoint'inde DELETE ve PUT yöntemleriyle başkalarının mesajları üzerinde işlem yapılabiliyordu
  • Silinen mesajlar sohbette This message was deleted olarak görünse de, saldırgan aynı DELETE isteğini çağırdığında orijinal mesajı geri alabiliyordu
  • Saldırgan, sohbet katılımcısı olmasa bile messageId kullanarak mesajları düzenleyebiliyordu
    • Kurban, bildirime dokunduğunda değiştirilmiş mesajı görebiliyordu
    • Mesajın altında edited ibaresi görünse de kimin düzenlediği gösterilmiyordu
    • Hesap adları benzersiz değil ve değiştirilebilir durumdaydı
  • ProfileUpdate GraphQL isteğindeki zayıf id parametresi kurbanın ID'siyle değiştirildiğinde ad, sexuality, yaş, bio gibi profil bilgileri güncellenebiliyordu
  • ProfileLike GraphQL isteğinde, profile#1 ile giriş yapılmışken profile#2'nin profile#3'e ‘Like’ göndermiş gibi görünmesi sağlanabiliyordu
    • Örnekte, rastgele bir profilden kendi profiline Like gönderildikten sonra bu Like premium hesabın Likes listesinde görünüyordu

Başkalarının sohbetlerine mesaj gönderme

  • Saldırgan, sohbetin katılımcısı olmasa bile başka kişilerin sohbetine mesaj gönderebiliyordu
  • Gerekli değer, önceki mesaj okuma açığından elde edilen channelID idi
  • channels/messaging/<channelID>/message yoluna POST isteği gönderildiğinde ilgili kanala mesaj ekleniyordu
  • Kurban bildirim alıyor ve mesajı görebiliyordu
  • Sistem bildirimi saldırganın adından gelmiş gibi gösterse de saldırgan profil adını değiştirebilir ve adlar benzersiz değildir

Açıklama zaman çizelgesi

  • 8 Mart 2024'te FORTBRIDGE tüm sorunları Feeld'e bildirdi
  • Aynı gün Feeld, testte kullanılan hesap bilgilerini istedi
  • 2 Nisan 2024'te FORTBRIDGE güncelleme talep etti ve Feeld inceleme sürdüğü gerekçesiyle yayının ertelenmesini istedi
  • 28 Mayıs 2024'te Feeld birden fazla düzeltme yayımladı ve tespit edilen maddelerin çözülüp çözülmediğini doğrulamak için en fazla 2 haftalık gecikme talep etti
  • 8 Haziran 2024'te ilk bildirim e-postasının üzerinden 3 ay geçmiş oldu
  • 15 Temmuz 2024'te Feeld, bazı sorunların daha karmaşık düzeltmeler gerektirdiğini bildirdi
  • 4 Ağustos 2024'te Feeld, kalan maddeler çözülene kadar yayının bekletilmesini istedi
  • 16 Ağustos 2024'te Feeld, kalan bulguları hafifletmeye yönelik değişiklikleri uyguladığını bildirdi
  • 8 Eylül 2024'te ilk bildirimden itibaren 6 ay geçmiş oldu
  • 10 Eylül 2024'te blog yazısı yayımlandı
  • Ağustos 2025'te ilgili araştırma DEF CON 33'te sunuldu

1 yorum

 
GN⁺ 2024-09-13
Hacker News yorumları
  • Yetki kontrolleri sanki yalnızca frontend’de uygulanmış gibi görünüyor; üstelik bir iki endpoint’te değil, neredeyse genelinde böyle
    Kavramsal olarak kaçınması kolay bir hata, ama benzer hataları kabul etmek istemeyeceğiniz kadar sık gördüm
    “Tüm yetkileri backend’de kontrol edin” çözümü, buffer overflow için “her yere sınır kontrolü koyun” demeye benzer hissettiriyor. Topluluk olarak ne yapılması gerektiğini biliyoruz, ama herkesin bunu tutarlı biçimde uygulamasını sağlamak kolay değil

    • Bence ikisi aynı şey değil. Buffer overflow kontrolü çok somut bir implementasyon ve dil ayrıntısıdır; kod tabanının herhangi bir yerinde ortaya çıkabilir
      Buna karşılık yetki kontrolü belirli bir sınırda gerçekleşir ve uygulamanın nasıl tasarlandığıyla ilgilidir. Bir projenin geliştirme biçimi üzerinde etkili olabildiğim her durumda backend API geliştirmesini frontend istemci kodundan net biçimde ayırmakta ısrar ettim. Deneyimime göre bu tür sorunlardan kaçınmak ve bunları test etmek çok daha kolaylaşıyor; ayrıca geliştiricilere yönelik bir API de “bedavaya” ortaya çıkıyor. Açıkçası bu yaklaşımı tercih etmemin başlıca nedeni de bu
    • Bunu karıştıracak kadar durum kötüyse sunucu tarafı koduna dokunmaman gerekir
    • Bir zamanlar bir web geliştiricisinin sıradan bir JavaScript iletişim kutusuyla frontend kimlik doğrulaması yaptığını yakalamıştım. Parolayı JS’e koyup basitçe karşılaştırıyordu
      Bunu öğrenmemin nedeni, lamp hesabının sahibinin verilerinin birdenbire tamamen kaybolduğunu söyleyerek iletişime geçmesiydi. Loglara baktığımda Google Bot’un dahili yönetim ekranındaki tüm “Delete” bağlantılarına tıkladığını gördüm. JavaScript opt-in olduğu için bu mümkün olmuştu. Geliştiriciyi arayıp ne yaptığını anlattım; o gün web tarafındaki insanlara duyduğum güvenin büyük kısmını kaybettim
    • Backend’de “otomatik DB API” kullanıyorsanız bunun çok kolay yaşanabileceğini düşünüyorum. Örneğin bazı otomatik GraphQL kurulumları akla geliyor
      Her gördüğümde işaretliyorum, ama istemci API’sinin kapsamı üzerine bazen çok az düşünülüyor; bu da oldukça endişe verici
    • Mobil uygulamalarda ne yazık ki epey yaygın. “Kullanıcı mobil uygulamayı didik didik mi inceleyecek?” mantığı
      Junior’ları, no-code’u, AI kodunu suçlamak istiyorum ama ben de onlar kadar tembel olduğum için sadece başımı sallayıp geçiyorum
  • Gerçek kişisel bilgileri girmemek için çok iyi bir neden. Örneğin doğum tarihi gibi şeyler
    Özellikle dating uygulamaları bu bilgileri istiyor gibi görünüyor, ama vermemek daha iyi. Gerçek doğum gününüzden bir yıl kadar sapacak farklı bir değer girmek daha mantıklı
    Bu dating uygulaması çok bilinen bir uygulama değil; BDSM, grup seks gibi farklı ilgi alanlarına sahip kişileri ve queer kullanıcıları hedefliyor. Dünyanın birçok yerinde bu tür bilgilerin son derece hassas olduğunu söylemeye gerek yok

  • Bu hafta çok para kazandığı için basında sıkça yer aldı
    https://www.theguardian.com/technology/article/2024/sep/08/t...

    • Bugünlerde iyi şeyler üretmektense kötü şeyler üretmenin çok daha fazla para kazandırdığını sık sık görüyoruz
    • The Guardian’ın bunu görmesini sağlamak gerek
  • Uygulama kategorisini düşününce bu, cezai ihmal düzeyinde bir başarısızlık

    • O ucuz yüklenici bendim. Üstlerim, takvim ve müşteri inceleyicilerin görebildiği bug’lar dışında hiçbir şeyi umursamıyordu
      ABD ve AB’de hapis tehdidi, veriyle ilgili sigorta ve veri sigortasının maliyeti tek caydırıcı unsur olacak gibi. Fotoğraflar LinkedIn’e koyulabilecek türden değilse dudak uçuklatan bedeller ödenmeli
      Elbette teşvikler örtbas etmeyi özendirmemeli
    • Şaka değilmiş. Bu zafiyetler 10 yıl önce bile utanç verici sayılırdı
  • Online dating alanı tam bir karmaşa. İşe yarar denebilecek hizmeti olan sadece 2-3 şirket var; onlar da ya kötü niyetli ya beceriksiz ya da ikisi birden
    Artık açık kaynak federatif dating servisi gibi bir şeye ihtiyaç olabilir. En azından verileri satmayan, çıplak fotoğrafları sızdırmayan, dövülmenize, tecavüze uğramanıza ya da öldürülmenize yol açmayan bir şey gerekli. Söylemesi kadar kolay olmayacak ama

    • Yıllardır böyle bir şey tasarlıyorum, ama asıl işimin yanında bunu yapacak kadar fazla dopaminim yok
      ActivityPub, Person kayıtlarının yayımlanması üzerinden bunu mümkün kılacak yapıya da sahip. Özellikle tek eşli olmayan, heteroseksüel olmayan ve cinsiyet normlarına uymayan ihtiyaçları önceliklendirirseniz inovasyon için muazzam bir alan var
      Ancak dating uygulamaları, içine girmesi gerçekten zor bir alan. Faydalı hale gelmesi için belirli bir bölgede birikmiş kullanıcı ölçeği gerekiyor; para kazanmaya başladığınızdaysa uygulama kaçınılmaz olarak daha az kullanışlı hale geliyor. okcupid’in kâr amacı gütmeyen niteliğini bıraktıktan sonra bozulmasının bir nedeni var
      Bir de moderasyon sorunu var
    • Çıplak fotoğrafların analog biçimde kalması gerektiğini düşünüyorum. Böylece dağıtım üzerinde neredeyse tamamen ve mutlak bir kontrolünüz olur
      Analog biçimi dijital kopyaya dönüştürmek istiyorsanız bu kişinin hakkıdır, ama hiçbir sistemin sızıntıyı ve dağıtımı engelleyecek kadar güvenli olmadığını ve gelecekte de olamayacağını bilmek gerekir
      Özellikle gençler, uzun vadede ortaya çıkabilecek ve çıkma olasılığı yüksek sonuçları ve utancı hesaba katmıyor. Böyle bir özellik sunmak, olumsuz sonuçlara davetiye çıkarmaktan ibaret
  • Gerçekten korkunç. Güvenlik konusunda hiç düşünmedikleri apaçık
    Oyun geliştiricisiyim; biz oyunu adil tutmak için bu şirketin kullanıcılarını güvende tutmaya harcadığından daha fazla çaba harcıyoruz. Davalarla paramparça edilmeliler

    • Sadece güvenlik değil, hiçbir şey üzerinde düşünmemiş gibiler
      Uygulamanın bug dolu olduğunu fark etmeden önce bile ilgi alanları bölümünün hiçbir bağlam sunmamasına çok şaşırmıştım. Örneğin neredeyse herkesin ilgi alanlarında Domination veya Submission vardı, ama hangi rolü istediğine dair hiçbir bağlam yoktu. O sahnede bunun temelden ne kadar yanlış olduğunu bilmemek, genel olarak hiçbir şey bilmemek demek
    • Dating uygulamalarındaki profillerin prensipte herkes tarafından erişilebilir olduğunu hesaba katmak gerekir. Uygulamayı açınca profiller görünür. ACL gibi bir şey yok
      Mesajlar ve özel fotoğraflar ayrı mesele
  • Provokatif söylemek gerekirse, bu GraphQL’in sorunu
    GraphQL, frontend’in veriyi sorgulamasını sağlar. Havalı bir şey, ama backend açısından bu çok opaktır ve genelde erişim denetiminden hiç anlamayan üçüncü taraf kütüphanelerle uygulanır.
    Erişim denetimini veritabanının kendisinde uygulamayacaksanız, backend kodunda GraphQL sorgusunu çözümleyip hangi kayıtların döndürülmesi ya da kısıtlanması gerektiğini anlamak çok zordur. Bunu veritabanında yapmak en kötüsü sayılmaz; frontend’de yapmaktan kesinlikle daha iyidir.
    Backend’de düzgün bir erişim denetimi uygulamak için sorguyu anlamanız, veritabanı şemasını kavramanız ve “user_id XXX ise bu bağlamda bu görseli görebilir mi/göremez mi” diye karar verecek modeller, sınıflar, fonksiyonlar vb. oluşturmanız gerekir. GraphQL’de bunu frontend’de uygulamak çok daha kolay olduğundan, onların da bunu yaptığı belli.
    GraphQL uygulamalarının iyi olduğunu söylemiyorum, sorun tamamen GraphQL’de de demiyorum. Demek istediğim, GraphQL backend’in sorguyu anlama ihtiyacını ortadan kaldırmaya çalıştığı için bu tür karmaşık güvenlik durumlarını zorlaştırıyor ve bu yüzden böyle bir hatayı yapmayı kolaylaştırıyor.
    [0] Örneğin belirli bir görsel kullanıcı profilinde herkese açık erişilebilir olabilir; ama yalnızca eşleşilen kişiye görünebilir, yalnızca sohbet bağlamında görünebilir (grup sohbetleri hariç) ya da engellenmiş bir kullanıcı için her zaman erişilemez olabilir. Sadece bu tek durum bile bir sürü karmaşık uç durum yaratabilir.

    • Oldukça kolay. Veri getiren her resolver’ı bir REST endpoint’i gibi ele alıp korumak ve CI build sırasında öğe ekleyen bir sorgu allowlist’i tutmak yeterli.
      AST ile uğraşmaya ya da sorgunun geri kalanının bağlamını anlamaya gerek yok. Fotoğrafları getiren resolver’da “ABC kullanıcısı XYZ kullanıcısının fotoğraflarını görebilir mi?” sorusunu yanıtlamak yeterli. Verimsizse bazı verileri önceden getirebilir ya da dataloader kullanabilirsiniz.
      Ancak GraphQL’i SQL’e çeviren sihirli bir kütüphane kullanıyorsanız durum değişir.
    • GraphQL’de özellik bazında erişim haklarını tanımlamanız ya da sorguları önceden derleyip allowlist’e almanız gerekir. Aksi takdirde her durumda veri sızar.
      https://hasura.io/docs/2.0/security/allow-list/
    • Kullanılabilir durumdaki herhangi bir üçüncü taraf GraphQL kütüphanesinin bir şekilde ACL uygulaması gerekir. En popüler olanlar da öyle görünüyor [1] [2]
      Basit bir fikir olarak yetkilendirmeyi veri modelinde uygulamak var. GraphQL’in, istek bağlamına göre yetkilendirme uygulayabilen kaynak modeline get ve list işlemlerini devretmesini sağlamak.
      [1] https://www.apollographql.com/docs/apollo-server/security/au...
      [2] https://docs.graphene-python.org/projects/django/en/latest/a...
    • HotChocolate kullanırken bu sorun yoktu. Entity’lere veya entity özelliklerine yetkilendirme kuralları kolayca verilebiliyor ve otomatik işleniyor. Mutation’lara da uygulanabiliyor.
  • Şaşırtıcı derecede sorumlu ve düşünceli bir ifşa olmuş.

    • “Discover profiles” menüsü ve beğeniler listesi ekran görüntülerine gerçek profilleri mi dahil etmişler? Öyleyse yüzleri kapatılmış olsa bile epey sorumsuzca.
    • Davranışları sözleriyle uyuşmuyor.
  • Çok şaşırtıcı değil. Kullanıyorum ama banka uygulamam kadar beceriksizce yapılmış derdim. Belki daha da kötü olabilir; neredeyse düzgün çalışmıyor.
    Bunu nasıl böyle yapabildiler bilmiyorum.

    • Ben kullandığımda da berbat durumdaydı. Ya garip bir memory leak ya da gizlilik sorunu vardı; değilse UX son derece kötü uygulanmıştı.
      Bu uygulama ve Fetlife’a bakınca, ilgili toplulukların kalite ne olursa olsun ilk çıkan uygulamada kalmaya devam etmesi konusunda büyük bir sorun var.
    • Ben kullandığımda topluluk iyiydi ama uygulama hiçbir zaman düzgün yazılmamıştı.
      Sonra bir süre önce yeni uygulamayı ve yeni sunucuyu herkese aynı anda dağıttıkları bir flag day yaptılar; çoğu kişi giriş bile yapamadı. Giriş yapabilenler de ücretli müşteriyse premium avantajlarını kaybetti; beğeniler ve sohbetler kayboldu vb. sorunlar yaşandı. Ben sonunda giriş yapamadım ve o noktada uygulamayı bıraktım.
  • Araştırmacıların ifşayı bu kadar uzun süre bekletmiş olmasına açıkçası şaşırdım.
    Böylesine ciddi bir gizlilik açığını kapatması için kötü yönetilen bir startup’a 6 ay verirseniz, en başta bu bilgileri toplayabilme ayrıcalığını kötüye kullanmaya devam ederler. Bence 2 ay verilip sonra ifşa edilmeli. İnsanların özel bilgileriyle zar atılmaması gerektiğini öğrenmeleri gerekiyor.