ORM Injection
Django ORM (Python)
In this post nasıl bir Django ORM'nin, örneğin aşağıdaki gibi bir kod kullanılarak savunmasız hale getirilebileceği açıklanmaktadır:
Tüm request.data'nın (bu bir json olacaktır) doğrudan veritabanından nesneleri filtrelemek için geçirildiğine dikkat edin. Bir saldırgan, beklenenden daha fazla veri sızdırmak için beklenmedik filtreler gönderebilir.
Örnekler:
Giriş: Basit bir girişte, içindeki kayıtlı kullanıcıların şifrelerini sızdırmaya çalışın.
Şifreyi brute-force ile kırmak, sızdırılana kadar mümkündür.
İlişkisel filtreleme: İşlemde kullanılacağı bile beklenmeyen sütunlardan bilgi sızdırmak için ilişkileri geçmek mümkündür. Örneğin, bu ilişkilerle bir kullanıcı tarafından oluşturulan makaleleri sızdırmak mümkünse: Article(
created_by
) -[1..1]-> Author (user
) -[1..1]-> User(password
).
Tüm makale oluşturmuş kullanıcıların şifrelerini bulmak mümkündür.
Çoktan çoğa ilişkisel filtreleme: Önceki örnekte, makale oluşturmamış kullanıcıların şifrelerini bulamadık. Ancak, diğer ilişkileri takip ederek bu mümkündür. Örneğin: Article(
created_by
) -[1..1]-> Author(departments
) -[0..*]-> Department(employees
) -[0..*]-> Author(user
) -[1..1]-> User(password
).
Bu durumda, makaleler oluşturan kullanıcıların departmanlarındaki tüm kullanıcıları bulabiliriz ve ardından şifrelerini sızdırabiliriz (önceki json'da yalnızca kullanıcı adlarını sızdırıyoruz ama daha sonra şifreleri sızdırmak mümkün).
Django Grup ve İzinlerinin kullanıcılarla olan çoktan çoğa ilişkilerini kötüye kullanma: Ayrıca, AbstractUser modeli Django'da kullanıcıları oluşturmak için kullanılır ve varsayılan olarak bu modelin İzin ve Grup tablolarıyla bazı çoktan çoğa ilişkileri vardır. Bu, temelde aynı grupta bulunan veya aynı izni paylaşan bir kullanıcıdan diğer kullanıcılara erişmenin varsayılan yoludur.
Filtre kısıtlamalarını atlama: Aynı blog yazısı,
articles = Article.objects.filter(is_secret=False, **request.data)
gibi bazı filtrelerin kullanımını atlamayı önerdi. is_secret=True olan makaleleri dökme olasılığı vardır çünkü bir ilişkiden Article tablosuna geri dönebiliriz ve gizli makaleleri gizli olmayan makalelerden sızdırabiliriz çünkü sonuçlar birleştirilmiştir ve is_secret alanı gizli olmayan makalede kontrol edilirken veri gizli makaleden sızdırılmaktadır.
İlişkileri kötüye kullanarak, gösterilen verileri korumak için tasarlanmış filtreleri bile atlatmak mümkündür.
Hata/Zaman bazlı ReDoS ile: Önceki örneklerde, filtrelemenin çalışıp çalışmadığına göre farklı yanıtlar alınması bekleniyordu ve bu, oracle olarak kullanılacaktı. Ancak, veritabanında bazı işlemler yapıldığında yanıtın her zaman aynı olması mümkün olabilir. Bu senaryoda, yeni bir oracle elde etmek için veritabanı hatası oluşturmak mümkün olabilir.
Aynı gönderiden bu vektörle ilgili:
SQLite: Varsayılan olarak bir regexp operatörüne sahip değildir (üçüncü taraf bir uzantının yüklenmesi gerekir)
PostgreSQL: Varsayılan bir regex zaman aşımına sahip değildir ve geri izlemeye daha az eğilimlidir
MariaDB: Bir regex zaman aşımına sahip değildir
Prisma ORM (NodeJS)
Aşağıdakiler bu gönderiden çıkarılan ipuçlarıdır.
Tam bulma kontrolü:
Tüm javascript gövdesinin sorgular gerçekleştirmek için prisma'ya geçirildiği görülebilir.
Orijinal gönderideki örnekte, bu, birisi tarafından oluşturulan tüm gönderileri kontrol eder (her gönderi birisi tarafından oluşturulur) ve o kişinin kullanıcı bilgilerini (kullanıcı adı, şifre...) de döndürür.
Aşağıdaki, bir şifreye sahip olan birinin oluşturduğu tüm gönderileri seçer ve şifreyi döndürecektir:
Tam where ifadesi kontrolü:
Saldırının where
ifadesini kontrol edebileceği duruma bir göz atalım:
Kullanıcıların şifrelerini doğrudan filtrelemek mümkündür:
startsWith
gibi işlemler kullanarak bilgi sızdırmak mümkündür.
Çoktan çoğa ilişkisel filtreleme ile filtrelemeyi atlama:
Category
-[*..*]-> Article
arasındaki çoktan çoğa ilişkileri kullanarak yayımlanmamış makaleleri sızdırmak mümkündür:
Aynı zamanda bazı döngüsel çoktan çoğa ilişkileri kötüye kullanarak tüm kullanıcıları sızdırmak da mümkündür:
Hata/Zamanlı sorgular: Orijinal yazıda, zaman tabanlı bir yük ile bilgi sızdırmak için optimal yükü bulmak amacıyla gerçekleştirilen çok kapsamlı bir test setini okuyabilirsiniz. Bu şudur:
Where the {CONTAINS_LIST}
is a list with 1000 strings to make sure the yanıtın doğru leak bulunduğunda geciktiğinden emin olmak için.
Ransack (Ruby)
These tricks where found in this post.
Ransack 4.0.0.0'ın artık aranabilir nitelikler ve ilişkiler için açık bir izin listesi kullanımını zorunlu kıldığını unutmayın.
Zayıf örnek:
Not edin ki sorgu, saldırgan tarafından gönderilen parametrelerle tanımlanacaktır. Örneğin, sıfırlama token'ını brute-force yapmak mümkün oldu:
Brute-forcing ve potansiyel ilişkilerle, bir veritabanından daha fazla veri sızdırmak mümkün oldu.
References
Last updated