Feeld flört uygulamasındaki güvenlik açıkları
(fortbridge.co.uk)- 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,
DiscoverProfilesGraphQL isteğinin yanıtından hedef kullanıcının streamUserId değeri alındıktan sonra, sohbet kanalı isteğindekimemberkoş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
ChatListQueryiçindeki zayıfprofileIdparametresi 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.comadresine 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
- Daha sonra fotoğraf
- Süre sınırlı fotoğraflar yüklenirken
visibilityMilliseconds:15000gibi 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.comtarafındaki yükleme akışı kullanılıyordu - Saldırgan, önceki mesaj okuma açığıyla URL'yi elde edip
u0026değerini&ile değiştirirse videoyu kimlik doğrulaması olmadan izleyebiliyordu
- Normal videolar
- Tek seferlik videolar saldırgan için yeniden oynatılabiliyordu, ancak alıcının uygulamasında bir kez izlendiğinde
video expiredolarak 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 deletedolarak 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
editedibaresi görünse de kimin düzenlediği gösterilmiyordu - Hesap adları benzersiz değil ve değiştirilebilir durumdaydı
ProfileUpdateGraphQL isteğindeki zayıfidparametresi kurbanın ID'siyle değiştirildiğinde ad, sexuality, yaş, bio gibi profil bilgileri güncellenebiliyorduProfileLikeGraphQL 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>/messageyoluna 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
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
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 öğ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
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
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...
Uygulama kategorisini düşününce bu, cezai ihmal düzeyinde bir başarısızlık
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
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
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
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
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
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.
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.
https://hasura.io/docs/2.0/security/allow-list/
Basit bir fikir olarak yetkilendirmeyi veri modelinde uygulamak var. GraphQL’in, istek bağlamına göre yetkilendirme uygulayabilen kaynak modeline
getvelistiş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...
Şaşırtıcı derecede sorumlu ve düşünceli bir ifşa olmuş.
Ç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.
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.
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.
Ör: https://news.ycombinator.com/item?id=41517747