Dreamweaver 8.0.2 ve CS3'te standart Kayıt Kümeleri içinde Dinamik SQL parametreleri kullanma

Açıklanan konular

Veritabanı güvenlik açığını giderme

Dreamweaver 8.0.2 ve CS3'te güvenliği artırmak için standart Kayıt Kümeleri içinde dinamik SQL parametreleri kullanma becerisini kaldırdık. Orijinal kod yerleştirilen veritabanlarından SQL enjeksiyonlara. ASP_VBS ve ColdFusion sunucu modelleri için hazırlanmış ifadeler kullanıldığında güvenlik açığı giderildi. İlk Kayıt Kümesi uygulandığında sayfaya bir işlev eklemek ve ardından bu işlevi PHP_MySQL için sayfadaki tüm Kayıt Kümelerinden çağırmak gerekiyordu. Bu teknik, ASP_VBS ve ColdFusion hazırlanan ifadeleriyle benzerdir.

Güvenlik açığını kapatmak için güvenlik konusunda esneklik sağladık. Dinamik SQL sorgularını işlemesi gereken uzantılara zaten sahip olan veya geliştirmeyi planlayan geliştiricilere ve kayıt kümelerini dinamik parametreleri kabul edecek şekilde özelleştirmek isteyen son kullanıcılara; bu özel Kayıt Kümelerini Dreamweaver içinden düzenleme yeteneği vermek istiyoruz.

SQL Enjeksiyonları ve önleme yöntemleri

SQL Enjeksiyonu, bir uygulamanın veritabanı katmanında meydana gelen güvenlik açığından yararlanan bir tekniktir. Güvenlik açığı, kullanıcı girdisi SQL ifadelerine katıştırılmış dizi tam çıkış karakterleri için yanlış şekilde filtrelendiğinde veya kullanıcı girdisi düzgün bir şekilde yazılmadığında ve bu nedenle beklenmedik bir şekilde yürütüldüğünde ortaya çıkar. Aslında, bir programlama veya komut dosyası dili diğerinin içine gömüldüğünde ortaya çıkabilecek daha genel bir güvenlik açığı sınıfından bir örnektir. Lütfen ek bilgi için Vikipedi'yi ziyaret edin.

Standart SQL Sorgusu örneği:

SELECT * FROM company_com WHERE name_com = '$companyName'

Yukarıdaki örnekte, $companyName değişkeni bir giriş formu alanından okunur, böylece kullanıcı hangi değerin gönderileceği ile ilgili tam kontrole sahip olur. En iyi senaryoda, kullanıcı şirket adına karşılık gelen girdiye "Adobe" (tırnak işaretleri olmadan) girdiğinde, verili SQL sorgusu şöyle görünür:

SELECT * FROM company_com NEREDE name_com = 'Adobe'

Ancak kullanıcıların web sitesini bozmak ve hassas bilgileri çalmak ve/veya veritabanını yok etmek isteyebilecekleri durumlar vardır. Yukarıdaki örnek göz önüne alındığında, bir SQL enjeksiyonu "blabla 'OR' 1 '=' 1" dizisi girilerek (etrafındaki tırnak işaretleri olmadan) kolayca elde edilebilir. Bu karakter dizisini vererek, kullanıcı tek bir şirket yerine tüm şirketlere erişebilecek. Yürütülen gerçek SQL:

SELECT * FROM company_com NEREDE name_com = 'blabla' VEYA '1' = '1'

Dahası, kullanıcı tüm company_com tablosunu silmek istiyorsa, bunu aşağıdaki "x"; DROP TABLE company_com; --" dizisini (çevresindeki tırnaklar olmadan) ileterek yapabilir. İşte tam SQL sorgusu:

SELECT * FROM company_com WHERE name_com = 'x'; DROP TABLE company_com; --'

Web sitenizi SQL enjeksiyonlarından korumak için aşağıdaki önlemlerden birini kullanın:

  • Verilen aralığın dışında kalan tüm diğer karakterleri otomatik olarak kaldırarak girişi izin verilen minimum karakter kümesiyle sınırlandırın.
  • Bir SQL sorgusunda (örneğin, tek tırnaklar kullanıldığında) sorunlara neden olabilecek tüm karakterlerden kaçının.
  • Hazırlanan ifadeleri kullanın.
  • Veritabanı erişim haklarını kullanın.
  • Saklı yordamları kullanın.

Hazırlanan ifadeleri kullanma bölümünde daha detaylı açıklanan hazırlanan ifadeleri kullanmanızı öneririz. Dreamweaver 8.0.2 ve CS3, ASP_VBS, ASP_JavaScript, Cold Fusion ve JSP sunucu modelleri için hazırlanan ifadeler yaklaşımını ve PHP_MySQL sunucu modeli için çıkış, kullanıcının girdi yaklaşımını kullanır. SQ enjeksiyon saldırıları hakkında ek bilgi için Örneklerle SQL Enjeksiyon Saldırıları bölümüne bakınız.

Hazırlanan ifadeleri kullanma

Dreamweaver 8.0.2 ve CS hazırlanan ifadeleri kullanır, çünkü bu çözüm bize gerçek SQL parametrelerinin verilen değerlerle (muhtemelen URL yoluyla gönderilir) değiştirilmesinin sayfada değil sunucuda yapılmasını garanti eder. Hazırlanan ifadeler ayrıca SQL'in kendisine iletilen değerin uygun veri türüne sahip olduğunu ve uygun çıkışı kullanmasını garanti eder (bir parametrenin int türünde olduğu söylenirse, kullanıcı bir harf gönderemez veya bir parametre metin türündeyse, iletilen dizinin tamamı kaçırılacak ve kullanıcının bir SQL enjeksiyonu gerçekleştirme şansı olmayacaktır).

ASP_VBS ve ASP_JS sunucu modelleri için hazırlanmış ifadeler

ASP_VBS ve ASP_JS için ADODB veritabanı katmanına güveniyoruz. Aşağıdaki örnek, sonuçları filtrelemek için dinamik bir SQL parametresi kullanan basit bir ASP_VBS Kayıt Kümesini gösterir:

... <% Dim Recordset1__MMColParam Recordset1__MMColParam = "1" If (Request.QueryString("id_com") <> "") Then Recordset1__MMColParam = Request.QueryString("id_com") End If %> <% Dim Recordset1 Dim Recordset1_cmd Dim Recordset1_numRows Set Recordset1_cmd = Server.CreateObject ("ADODB.Command") Recordset1_cmd.ActiveConnection = MM_connContacts_STRING Recordset1_cmd.CommandText = "SELECT * FROM company_com WHERE id_com = ?" Recordset1_cmd.Prepared = true Recordset1_cmd.Parameters.Append Recordset1_cmd.CreateParameter("param1", 5, 1, -1, Recordset1__MMColParam) ' adDouble Set Recordset1 = Recordset1_cmd.Execute Recordset1_numRows = 0 %> ...

ColdFusion sunucu modeli için hazırlanan ifadeler

ColdFusion hazırlanmış ifadeler için dahili destek sunar. Aşağıdaki örnek, sonuçları filtrelemek için dinamik bir SQL parametresi kullanan basit bir ColdFusion Kayıt Kümesini gösterir:

... <cfparam name="URL.id_com" default="1"> <cfquery name="Recordset1" datasource="company_employee"> SELECT * FROM company_com WHERE id_com = <cfqueryparam value="#URL.id_com#" cfsqltype="cf_sql_numeric"> </cfquery> ...

PHP_MySQL sunucu modeli için simüle edilmiş hazırlanmış ifadeler

PHP için hazırlanan ifadeler MySQL 4.1 ile kullanılabilir hale geldi, ancak MySQL'in önceki sürümlerini de desteklemek istediğimizden, aslında aynı şeyi yapan özel bir işlev uygulamaya karar verdik. Aşağıdaki örnek, sonuçları filtrelemek için dinamik bir SQL parametresi kullanan basit bir PHP Kayıt Kümesini gösterir:

... <?php if (!function_exists("GetSQLValueString")) { function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") { $theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue; $theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue); switch ($theType) { case "text": $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL"; break; case "long": case "int": $theValue = ($theValue != "") ? intval($theValue) : "NULL"; break; case "double": $theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL"; break; case "date": $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL"; break; case "defined": $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue; break; } return $theValue; } } $colname_Recordset1 = "-1"; if (isset($_GET['id_com'])) { $colname_Recordset1 = $_GET['id_com']; } mysql_select_db($database_connContacts, $connContacts); $query_Recordset1 = sprintf("SELECT * FROM company_com WHERE id_com = %s", GetSQLValueString($colname_Recordset1, "int")); $Recordset1 = mysql_query($query_Recordset1, $connContacts) or die(mysql_error()); $row_Recordset1 = mysql_fetch_assoc($Recordset1); $totalRows_Recordset1 = mysql_num_rows($Recordset1); ?> ...

Standart Kayıt Kümelerinde dinamik parametrelere izin verme

Dinamik parametrelere izin verirken ve elde edilen kodu Dreamweaver'daki Sunucu Davranışları paneli aracılığıyla düzenlenebilir tutarken SQL enjeksiyonlarına karşı nasıl koruyabiliriz? Çözüm, dinamik parametreleri klasik SQL parametreleri olarak belirtmek yerine SQL sorgusunun kendisine eklemektir (bunlar hazırlanan ifadeler yoluyla SQL'den çıkarılır veya eklenir).

Önemli: Kullanıcılar Dreamweaver 8.0.2 veya CS3 ile birlikte gelen Nesneleri ve Sunucu Davranışlarını kullanarak bu kodu üretemez (Örnek: Sunucu Davranışları paneli veya Ekle çubuğu aracılığıyla Kayıt Kümesi ekleme). Bu çözüm, kullanıcının kodu manuel olarak düzenlemesini veya bu kodu oluşturan üçüncü taraf bir uzantı yüklemesini gerektirir. Güvenli kod yazma sorumluluğu kullanıcıya veya üçüncü taraf yazılım geliştiricisine aittir.

Bu yöntemin amacı, deneyimli geliştiricilerin dinamik SQL sorguları oluşturmalarına izin vermektir. Bu çözümün yanlış kullanımı, bir bilgisayar korsanına istenmeyen ayrıcalıklar alma ve/veya web sayfalarını ve veritabanını bozma imkanı verir. SQL enjeksiyonlarının riskini azaltmak için SQL Enjeksiyonları ve önleme yöntemleri'ne bakınız.

Bu çözümün kullanılacağını belirlediğimiz ana durumlar şunlardır:

  • Dinamik parametreleri kabul etmek için manuel olarak bir SQL sorgusu oluşturma/güncelleme.
  • Dinamik parametreler oluşturmak için mevcut uzantıları oluşturun/yükseltin.

Her iki kullanım durumu da aşağıdaki paragraflarda detaylandırılacaktır.

Kayıt kümesini Dreamweaver içinden hala düzenlenebilir tutarken dinamik parametreleri kabul etmek için el ile bir SQL sorgusu oluşturma/güncelleme

Aşağıdaki örnekte kullanıcı dinamik bir tabloya sıralama işlevi eklemek istiyor. URL'de kullanılacak dosyaları ve sıralama yönünü (artan veya azalan) belirtirken sayfayı yeniden yüklemeye karar verir. İlk URL örneği:

http://www.mydomain.com/index.php?sortCol=name_com&sortDir=asc

Bu davranışı Dreamweaver'da Sunucu Davranışları'nı kullanarak gerçekleştirmek için el kodlaması gerekir. Aşağıdaki kod örnekleri, her sunucu modeli için yapılması gereken değişiklikleri gösterir.

Önemli: Aşağıdaki örneklerin hiçbirinin SQL enjeksiyonlarına karşısında geçerli olmadığını lütfen unutmayın. Yalnızca eğitsel işlevleri vardır ve üretimde olduğu gibi kullanılmamalıdır. Örnekler mümkün olduğunca basit tutmak için kurşun geçirmez değildir. SQL enjeksiyonlarına karşı korunmalısınız. Ek bilgi için lütfen SQL Enjeksiyonları ve önleme yöntemleri'ne bakınız.

ASP_VBS

Öncesi:

... <% Dim Recordset1 Dim Recordset1_cmd Dim Recordset1_numRows Set Recordset1_cmd = Server.CreateObject ("ADODB.Command") Recordset1_cmd.ActiveConnection = MM_connContacts_STRING Recordset1_cmd.CommandText = "SELECT * FROM company_com" Recordset1_cmd.Prepared = true Set Recordset1 = Recordset1_cmd.Execute Recordset1_numRows = 0 %> ...

Sonra:

... <% Dim orderBy: orderBy = "" If (Request.QueryString("sortCol") <> "") Then orderBy = "ORDER BY " & Request.QueryString("id_com") If (Request.QueryString("sortDir") <> "") Then orderBy = orderBy & " " & Request.QueryString("sortDir") End If End If %> <% Dim Recordset1 Dim Recordset1_cmd Dim Recordset1_numRows Set Recordset1_cmd = Server.CreateObject ("ADODB.Command") Recordset1_cmd.ActiveConnection = MM_connContacts_STRING Recordset1_cmd.CommandText = "SELECT * FROM company_com " & orderBy & "" Recordset1_cmd.Prepared = true Set Recordset1 = Recordset1_cmd.Execute Recordset1_numRows = 0 %> ...

ColdFusion

Öncesi:

... <cfquery name="Recordset1" datasource="company_employee"> SELECT * FROM company_com </cfquery> ...

Sonra:

... <cfparam name="URL.sortCol" default=""> <cfparam name="URL.sortDir" default="ASC"> <cfset orderBy=""> <cfif (#URL.sortCol# NEQ "")> <cfset orderBy="ORDER BY #URL.sortCol# #URL.sortDir#"> </cfif> <cfquery name="Recordset1" datasource="company_employee"> SELECT * FROM company_com #orderBy# </cfquery> ...

PHP_MySQL

Öncesi:

... <?php mysql_select_db($database_connContacts, $connContacts); $query_Recordset1 = "SELECT * FROM company_com"; $Recordset1 = mysql_query($query_Recordset1, $connContacts) or die(mysql_error()); $row_Recordset1 = mysql_fetch_assoc($Recordset1); $totalRows_Recordset1 = mysql_num_rows($Recordset1); ?> ...

Sonra:

... <?php $orderBy = ""; if (isset($_GET['sortCol'])) { $orderBy = "ORDER BY " . $_GET['sortCol']; if (isset($_GET['sortDir'])) { $orderBy .= " " . $_GET['sortDir']; } } ?> <?php mysql_select_db($database_connContacts, $connContacts); $query_Recordset1 = "SELECT * FROM company_com " . $orderBy . ""; $Recordset1 = mysql_query($query_Recordset1, $connContacts) or die(mysql_error()); $row_Recordset1 = mysql_fetch_assoc($Recordset1); $totalRows_Recordset1 = mysql_num_rows($Recordset1); ?> ...

Kayıt kümesini Dreamweaver içinden hala düzenlenebilir tutarken dinamik parametreleri oluşturmak için mevcut uzantıları oluşturma/güncelleme

Şimdi yukarıdaki senaryoyu tek farkla hayal edin, kullanıcı dahili işlevsellik ve elle-düzenleme kombinasyonuna güvenmek yerine uygun kodu oluşturacak bir uzantı oluşturmak istemektedir. Yeni uzantı ASP_VBS, ColdFusion ve PHP_MySQL sunucu modelleri için doğru kodu üretmelidir.

Önemli: Aşağıdaki bölümlerde yalnızca dinamik bir SQL sorgusu oluşturmak için URL parametrelerindeki değerleri kullanacak kod oluşturmaya odaklanacağız. En çok üstünde durulan, kodu Dreamweaver tarafından tanınacak ve standart Dreamweaver arayüzlerinden düzenlenebilir olacak şekilde oluşturmaktır. Bu öğretici, giriş verilerinin doğrulanmasını (URL parametreleri aracılığıyla) işlemeyecek veya SQL kodunun karmaşıklığı bu öğreticinin kapsamı dışında kaldığından, nihai SQL'i SQL enjeksiyonlarının herhangi bir girişimine karşı korumaz. Gelişrtirici yalnızca nihai SQL'i SQL enjeksiyonlarından korumakla sorumludur.

Bağlantıyı ve tabloyu girdi olarak kabul eden ve tüm kayıtları görüntüleyen dinamik bir tablo oluşturan bir demo uzantısı sunuyoruz. Oluşturulan SQL'i yukarıdaki örneklerde gösterildiği gibi orderBy değişkenini içerecek şekilde günceller. Uzantı Dreamweaver 8.0.2 ve CS3 için tasarlanmıştır. Oluşturulan kod kusursuz değildir, çünkü amaç standart Dreamweaver arayüzleri kullanılarak düzenlenebilir kalan dinamik parametreler içeren Kayıt Kümeleri oluşturmaktır. Uzantı kaynak kodu şurada bulunur: Kullanıcının Yapılandırma klasörü.

Aşağıdaki kod örneklerinin tümünde, sortCol ve sortDir URL parametreleri aracılığıyla sıralama işlevini etkinleştirmek için vurgulayıcı bölümler eklenmiştir.

ASP_VBS

ASP_VBS sunucu modeli için uygun SQL sorgusunu oluşturan kod, Kullanıcı Yapılandırma Klasörü'ndeki "[USER_CONFIGURATION_FOLDER]/Commands/My Dynamic Table.js" dosyasında bulunur. Dikkate değer değişiklik 130. satırdadır:

... 130: paramObj.encodedSQL = "SELECT * FROM " + paramObj.table + " \" & orderBy & \""; ...

MyDynamicTable ASP_VBS sunucu davranışı için katılımcılar dosyası, sayfaya "orderBy" değişken tanımını ilave eden ek bir katılımcı içerir:

<group name="MyDynamicTable" version="9.0"> <groupParticipants> <groupParticipant name="connectionref_statement" /> <groupParticipant name="MyDynamicTable_orderBy" /> <groupParticipant name="recordset_main" /> <groupParticipant name="repeatedRegion_init2" /> <groupParticipant name="DynamicTable_main" /> <groupParticipant name="recordset_close" /> </groupParticipants> </group>

ColdFusion

Kullanıcı Yapılandırma Klasörü içindeki aynı "[USER_CONFIGURATION_FOLDER]/Commands/My Dynamic Table.js" dosyası ayrıca ColdFusion sunucu modeli için kod içerir; bu durumda ilgili değişiklik 138. satırdadır:

... 138: paramObj.SQLStatement = "SELECT * FROM " + paramObj.table + " #orderBy#"; ...

MyDynamicTable ColdFusion sunucu davranışı için katılımcılar dosyası, sayfaya "orderBy" değişken tanımını ilave eden ek bir katılımcı içerir:

<group name="MyDynamicTable" version="9.0"> <groupParticipants> <groupParticipant name="MyDynamicTable_orderBy" /> <groupParticipant name="Recordset_main" /> <groupParticipant name="DynamicTable_main" /> <groupParticipant name="RepeatedRegion_pageNum" /> <groupParticipant name="RepeatedRegion_maxRows" /> <groupParticipant name="RepeatedRegion_startRow" /> <groupParticipant name="RepeatedRegion_endRow" /> <groupParticipant name="RepeatedRegion_totalPages" /> </groupParticipants> </group>

PHP_MySQL

Uzantıdaki son sunucu modeli PHP_MySQL'dir. Kullanıcı Yapılandırma Klasörü içinde yer alan "[USER_CONFIGURATION_FOLDER]/Commands/My Dynamic Table.js" dosyasındaki ilgili değişiklik 122. satırdadır:

... 122: paramObj.SQLStatement = "SELECT * FROM " + paramObj.table+ " \" . $orderBy . \""; ...

MyDynamicTable PHP_MySQL sunucu davranışı için katılımcılar dosyası, sayfaya "orderBy" değişken tanımını ilave eden ek bir katılımcı içerir:

<group name="MyDynamicTable" version="9.0"> <groupParticipants> <groupParticipant name="Connection_include" /> <groupParticipant name="MyDynamicTable_orderBy" /> <groupParticipant name="EditOps_SQLValueString" /> <groupParticipant name="Recordset_main" /> <groupParticipant name="DynamicTable_main" /> <groupParticipant name="Recordset_close" /> </groupParticipants> </group>

Avantajları

Yukarıda tarif edilen yöntemin çeşitli avantajları vardır:

  • Daha gelişmiş geliştiriciler, dinamik bir şekilde daha karmaşık SQL'ler oluşturmak için SQL enjeksiyon güvenlik açığından yararlanabilir.
  • Oluşturulan Kayıt Kümeleri yine de Dreamweaver içinden düzenlenebilir olacaktır.
  • Dinamik SQL parametreleriyle Kayıt Kümeleri oluşturan mevcut Dreamweaver uzantılarına entegre etmek zor değildir.
  • Dreamweaver tarafından oluşturulan varsayılan kod değişmeden kalır; dinamik sorgulara ihtiyaç duymayan geliştiriciler (ve müşterileri) Dreamweaver tarafından yazılan kodun güvenli olduğundan emin olabilir.

Dezavantajları

Dreamweaver varsayılan olarak bu yöntemi destekleyecek şekilde tasarlanmadığından, aşağıdakiler de dahil olmak üzere bazı dezavantajları vardır:

  • Bu belgede açıklanan yöntem kullanılarak oluşturulan kod SQL enjeksiyonlarına karşı savunmasızdır ve bu nedenle başka yollarla korunması gerekir. Bu tür koruma yöntemlerinin listesi aşağıdakileri içerir, ancak bunlarla sınırlı değildir:
    • Son kullanıcının web sayfasını ve/veya veritabanını oluşturmak için SQL enjeksiyon yöntemini kullanamayacağından emin olun;
    • Gerçek SQL'e ulaşmadan argümanlardan kaçının;
    • Kullanıcı kodunuzu kırmayı başarsa bile hassas bilgileri çalmayacağından ve/veya veritabanını oluşturmayacağından emin olun.
  • Dreamweaver'ın sonraki sürümüne kadar düzeltilemeyecek bilinen iki sorun:
    • ColdFusion: Basit Kayıt Kümesi kullanıcı arabirimi, düzenlendikten ve yeniden uygulandığında değişken adlarının etrafındaki karmaları SQL sorgusundan kaldırır
    • ColdFusion, ASP_VBS, ASP_JS: SQL sorgusu değişken adları içerdiğinde, Gelişmiş Kayıt Kümesi Kullanıcı Arabirimi'nden sınama düğmesi çalışmaz

Kullanıcının Yapılandırma klasörünü bulma

  • Windows XP

    C:\Documents and Settings\[username]\Application Data\Adobe\Dreamweaver 9\Configuration
  • Windows Vista

    C:\Users\[username]\AppData\Roaming\Adobe\Dreamweaver 9\Configuration
  • Mac OS 10.4.x

    /Users/[username]/Library/Application\ Support/Adobe/Dreamweaver\ 9/Configuration
Adobe logosu

Hesabınıza giriş yapın