Bu makalede, veri tabanlarına bağlanırken kullanılan connection stringleri, çalışma zamanında oluşturup, yönetebilmeyi sağlayan .Net ekosistemindeki DbConnectionStringBuilder sınıfına değineceğim.
Başlamadan önce bu sınıfı keşfetmemdeki bir olayı anlatmak istiyorum.
Çalıştığım şirkette, .NET ile yazılmış bir projede Fortify ile periyodik güvenlik taramalarında "Connection String Parameter Pollution" kategorisinde yüksek kritik seviyesinde bir bulgu verdi. Bunu çözebilmek için araştırma yaparken bu özelliğe denk geldim.
"Connection String Parameter Pollution" zaafiyeti, herhangi bir atakta; doğrulanmayan bir veriden dolayı connection stringlerinde mevcut parametre değerlerini geçersiz kılabilir, yeni bir parametre enjekte edebilir.
Örnek:
Aşağıdaki kod bloğunda, form verisinde pass parametresine değer olarak "xxx; Integrated Security = true" atansın. Bunu string birleştirme ile yapmaktadır.
...
string password = Request.Form["pass"]; //form parameter 'pass'
SqlConnection dbConnection = new SqlConnection("Data Source = 127.0.0.1; Initial Catalog = BLOGCUMUHENDIS_DB; User ID = sa; Password = " + password + ";");
...
Oluşan connection string aşağıdaki gibidir.
"Data Source = 127.0.0.1; Initial Catalog = BLOGCUMUHENDIS_DB; User ID = sa; Password = xxx; Integrated Security = true; "
Bu değer, uygulamanın normal kimlik doğrulamasını aşıp uygulamanın çalıştığı işletim sistemi hesabını kullanarak veritabanına bağlanmasını sağlayacaktır. Böylece, saldırganın geçerli bir parola olmadan veritabanına bağlanabileceği ve veritabanına doğrudan sorgular gerçekleştirebileceği anlamına gelir.
Konumuza geri dönelim;
DbConnectionStringBuilder sınıfı, kullanılan veri tabanı teknolojisine göre farklı sağlayıcılara (providers) sahiptir. SqlClient ile veri tabanı sorgulaması için SqlConnectionStringBuilder sınıfını kullanmalısınız.
Her bir provider'deki sınıf, DbConnectionStringBuilder sınıfından miras alınmaktadır.
Provider | ConnectionStringBuilder Sınıfı |
---|---|
System.Data.OleDb | System.Data.OleDb.OleDbConnectionStringBuilder |
System.Data.SqlClient | System.Data.SqlClient.SqlConnectionStringBuilder |
System.Data.Odbc | System.Data.Odbc.OdbcConnectionStringBuilder |
System.Data.OracleClient | System.Data.OracleClient.OracleConnectionStringBuilder |
Bunu bir örnekle daha anlaşılır kılalım. SqlConnectionStringBuilder sınıfını kullanarak parametreleri tanımlanmamış connection stringin önemli parametrelerini çalışma anında tanımlayalım.
Üstteki görselde görebileceğiniz gibi SqlConnectionStringBuilder sınıfı oluşturmak için connection string kullanıp kullanmamaya göre iki farklı seçenek bulunuyor.
Config dosyasında veri tabanı bağlantı yolu vardır. SqlConnectionString ismindeki key'de göreceğiniz gibi veritabanı adı, sunucusu, kullanıcı adı ve parola bilgisi mevcut değildir.
SqlConnectionStringBuilder sınıfındaki propertylerin olduğu SqlConnectionString isminde bir DTO sınıfı oluşturuldu. AutoMapper gibi DTO paketleri kullanmak istemedim.
Önce configden değeri aldıktan sonra connection string özelliğini okuyoruz. (3. ve 7. satır)
Ardından gelen verileri ConvertFromDTO metodu ile builder sınıfına ait propertylere atanır ve SqlConnectionStringBuilder tipinden bir nesne döndürürüz. (10. satır) Kritik olan kısım connection stringi kullanarak ilgili propertylere atama yapar.
Not: Farklı propertyler eklemek istersek metodu güncelleyebilirsiniz.
Builder nesnesine ait ConnectionString propertysi ile çalışma anında oluşturulan veri tabanı bağlantı yolu tutulur.
Geliştirilen yapıyı console uygulamasından da çağıralım. Oluşan connection stringi görseldeki çıktıda görebilirsiniz.
Builder nesnesinin propertyleri aşağıdaki gibidir. Verilen bir connection string için ilgili builder sınıfından propertyleri inceleyebilir, değişiklikler yapılabilirsiniz.
Özetle;
DbConnectionStringBuilder sınıfı ile çalışma anında veri tabanı bağlantı yolundaki özellikleri inceleyebilir, parametre atamaları yapabilirsiniz. Hatta kod bloğunuzu da güvenli hale getirebilirsiniz.
Yazının faydalı olmasını umarak çalışmalarınızda kolaylıklar diliyorum :)
Kaynak
Yorumlar
Yorum Gönder