pillinetwork hesabınızla giriş yapın.

sql injection ve çözümü

asp ile programlama yapanların bilmesi gereken en temel problem olan sql injection, aslında çok basit çözümü olan bir sorundur.

Öncelikle sql injection açığı nedir? sql injection sayfa.asp?id=1 gibi algoritmaları olan sayfalarınıza kastı olan kişilerin kullandıkları bir hack yöntemidir. mesela formlarda veya querystring yöntemini kullanan programlamalarda sayfa.asp?id=1 de id=1 yerine id=<script> yazarsanız sisteminiz bozulabilir. Bu yöntemi kullanan kişi yönetim panelinize bile girebilir.

normalde sayfa.asp?id=1 olarak gönderilen veri sayfa.asp sayfasında

1
2
3
4
5
6
<%
id=request.querystring("id")
Set recordset = Server.CreateObject("ADODB.Recordset")
sql="select * from tablo where idnumarasi="&id&""
recordset.open sql,dbbaglantisi,1,3
%>

gibi bir algoritma ile yürür. Ancak sayfa.asp?id=1 'i kendi amaçları doğrultusunda değiştiren kişiler kalıcı sorunlara neden olabilir.

Bu olayı engellemenin birkaç yolu var. En basit olan yöntem isnumeric yöntemidir. Bu kod gelen verinin sayı olup olmadığını kontrol eder. böylece sayı haricinde birşey gelirse hata verdirebilir veya hiçbir işlem yapmadan sayfayı yönlendirebilirsiniz.

1
2
3
4
5
6
7
<%
id=request.querystring("id")
if isnumeric(id)=false then
response.write "hatalı istek"
response.end
end if
%>

Diğer bir yöntem replace yöntemidir. Aşağıdaki kodlarla gelen veriyi istediğiniz doğrultuda değiştirebilir ve filtreleyebilirsiniz. Mesela kullanıcı size sayfa.asp?id=<script> şeklinde bir veri gönderdiyse siz bunu replace komutu ile değiştirebilirsiniz.

Önce replace fonksiyonunu vereyim.

1
2
3
4
5
6
7
<%
function koru(kelime)
kelime=replace(kelime, "<" , "" )
kelime=replace(kelime, "<script>" , "" )
koru=kelime
end function
%>

bu kodlarla eğer id olarak < veya <script> gelirse bu verileri boşluğa çevir komutu verdik. hemen ardından da request nesnemize bu fonksiyonu ekliyoruz.

1
<% id=koru(request.querystring("id"))%>

böylece sql injection sorununu çözmüş olduk. amatör programcılar arasında bolca sözü geçen 'or' açığı da bu yöntemle çözülür. mantık aynıdır. replace komutu ile ' işaretlerini sildirirseniz problem ortadan kalkar.

Spacer
Spacer
/* firederick yazdı. 03 Şubat 2009 09:58. 28 yorum var */

Yorumlar

Güzel bir yazı. Bir kaç şey eklemek isterim.

Sql Injection ataklarından korunmak ve daha okunabilir veri erişimi sağlamak için Parametrik sql sorgularını kullanmanız hem bakım açısından, hemde okunabilirlik açısından daha iyi sonuçlar verebilir.

Örneğin:
Bağlantınızın açıldığını ve adovbs.inc eklendiğini varsayıyorum...


Set Cmd = Server.CreateObject("ADODB.COMMAND")
Cmd.ActiveConnection = Baglantiniz
Cmd.CommandType = adCmdText
Cmd.CommandText ="select * from tablo where idnumarasi=?"

Set p_idnumarasi = Cmd.CreateParameter ("idnum", adInteger, adParamInput)
p_idnumarasi.Value = GelenId
Cmd.Parameters.Append p_idnumarasi

Cmd.Execute()
Set Cmd = Nothing

/* Loading... */

ben ASP'den pek anlamam, PHPciyim.. simdi birseyi merak ettim; verdigin ornekte ID degeri rakamsal olarak giriliyor ve onlemi isnumeric fonksiyonuyla almissin.. peki ya girilecek deger numerik degilse ne olacak?
yaziGoster.asp?yazar=Mehmet seklinde bir yapi oldugunda ne gibi onlem aliniyor, onu da belirtirsen yeni baslayan ASPcilerin isine yarayacaktir.

Gelmesi beklenen veri alfanümerik ise bu durumda isnumeric fonksiyonunu kullanmak gereksiz oluyor doğal olarak. Yapılacak iş, yukarıda bahsedilen Replace fonksiyonuyla gönderilmesi muhtemel bir scripti önlemektir. Bu durumda zaten isnumeric yöntemini kullanmanıza gerek kalmıyor. Aşağıda sorunlu karakterleri değiştiren bir fonksiyonun kodlarını sunuyorum:

 

Function kodYok(metin)
    duzelt = metin
    duzelt = Replace(duzelt, "<script", "")
    duzelt = Replace(duzelt, "<", "")
    duzelt = Replace(duzelt, ">", "")
    duzelt = Replace(duzelt, "'", "´")
    kodYok = duzelt
End Function


 
Bir metni önce bu fonksiyondan geçirirseniz, metindeki sakıncalı olabilecek kodlar ya da karakterler ayıklanır. Bu fonksiyondaki satırlar artırılarak, örneğin Türkçe karakterlerin de noktasız karşılıklarıyla değiştirilmesi v.s. sağlanabilir (Örn Ş -> S gibi)

ama öyle bir zaman gelir ki kötü amaçlı karakterleri ayıklamak yerine kötü karakter görüldüğünde hata mesajıda yürütülmek istenebilir. bu bağlamda temizlik fonksiyonları bu görevleri yürütebilecek esneklikte hazırlanmalıdır.

sql injection problemleri ile karşılaşmamak için SQL server kullanıyorsak Stored Procedure kullanılmasını öneririm.

.net ile kodlama yapılıyorsa parametre ekleyerek execute edilmesi bu problemleri oradan kaldıracaktır.
örnek (c#);

cmd.Parameters.AddWithValue("@param1", Degisken);

bence en iyisi ardabalkan'ın paylaştığı kod ama onda da eksik var " işareti filtrelenmiyor

/* www.pcturk.org ile uğraşıyorum :| */

edit: yorumlarda bazı karakterler gözükmüyor

Kaç kullanıcının sql injection yapmaya çalıştığını ve hangi injection parametrelerini kullandıklarını da log olarak tutmanızda fayda vardır.

Bunu da önce alınan stringin ham haliyle , temizlenmiş halini karşılaştıran bir fonksiyon yazarak yapabilirsiniz.

Klasik bir zararlı kod temizleme fonksiyonu kullanırım, yeter ki temizlesin yeter gerisi beni alakadar etmez diyorsanız da haklısınızdır. Bu tür durumları takip etmek isterseniz de haklısınızdır.

arkadaslar numerik olmayan yerlerde sadece tek tırnak karakterini engellesiniz yeter. sql de iki tane tane tek tırnak içindeki yazılar full text olarak gözükür yani onun içinde update te yazsanız select te olsa hiç bi sakıncası olmaz.

eğer yazıda tek tırnak kullanacaksanız da tek tırnağı ikitane tek tırnakla replace edin.

Hala sql injection yapan varmıdır acaba :)

@lonelycavalry

evet dediÄŸin doÄŸru

bize öyle bir fonksiyon yazabilir misin?

/* www.pcturk.org ile uğraşıyorum :| */

Asp kullananlar için kendim kullandığım fonksiyon altta. Ben abartıp biraz fazla olasılık ekledim ama isteyenler modifye etsin. Mantık zaten anormal kolay istenen dile çevrilebilir.

Function killChars(strWords)

dim badChars
dim newChars

badChars = array(" select"," drop",";","--"," insert"," delete"," dbo","sysdatabases","sysobjects","syscolumns","collate"," having"," update"," group"," create","union","xp_","="," or ","'","<",">","*","'","-")
newChars = strWords

For i = 0 To uBound(badChars) newChars = replace(newChars, badChars(i), "")
Next

killChars = newChars

End Function

/* Bilardo */

Hmmm, bu fonksiyon benim eklediğimden daha kullanışlı. Yasak karakterleri bir dizi değişkende tutmak...

peki ya kullanıcının girdiği formda bu karakterleri de kabul etmek istiyorsak. örneğin html girişi için. bu şekilde bir filtreleme yapmak yerine \ eklemek daha mantıklıdır. bunun için php 'de mysql_real_escape_string kullanılabilir.

abi manyakmısınız hala asp kullanıyorsunuz
bir arkadaşımda bu yöntemle yapmıştı forumlarda kullanıyordu

"benim gardropum çok boş" yazmak istedim "benim garum çok boş" yazdı aman ne güzel...

alın size sql injectionun kesin çözümü

SqlParameter[] params = { new SqlParamater("@ID",this.ID) }
Microsoft.SqlHelper.Database.ExecuteNonQuery(SqlString, params);

al bitti

Sırf yorum yazmak için yazmayın! Haddinizi de aşmamaya özen gösterin! İnsanlara hakaret ederek bir yerlere gelemeyeceğiniz gibi bu faydalı merkezin seviyesini düşürmeye de hakkınız bulunmamaktadır!

Manyağız ve ASP kullanıyoruz. Bu sevgili kardeşimiz muhtemelen benden 15-20 yaş küçüktür. Bu nedenle yaptığı edepsizliği bu seferlik okumamış oldum. Kod yazan, ama gerçekten kod yazan adamların topuluğu olduğunu düşünerek üye olup takip etmeye başladığım bu sitede -ki hiçbir şekilde bir forumu blog sitesini düzenli takip etmezdim- daha uzun süre kalamayacaksam, bu geleneksel Türk mantığıyla yazıp çizen gençler yüzünden olacaktır. Kodaman.org için benim kaybım büyük bir kayıp olmayabilir ama presitj kaybolursa herşey gider.

Adam gibi fonksiyon yazarsanız, tüm diller bir şekilde sizin talebinizi karşılayacaktır. Yazım kuralları sık sık değişen (syntax) PHP ve sürekli güvenlik güncellemesi vs. yayınlanan .NET yanında klasik ASP birileri için hâlâ güvenli liman olabilir ya da adamın başka dil öğrenmeye vakti, enerjisi vesairesi yoktur. Edepsizliğin âlemi yok.

asp de yazılıp düzeltilmeye çalışan buglarla vakit harcanacağına asp.net öğrenilebilir ben sadece fikir verdim 2002 yılından beri .net ile ilgileniyorum
bu arada yazdığım sert yorumlardan dolayı siteden çekip gidicekseniz kendinize güveniniz yoktur derim..

kodu herkes yazar ama doğru kod yazmak önemlidir bende insanlara bir şekilde bunu anlatmaya çalışıyorum her önüne gelen ben programcıyım demesin sonra.

ps: söz meclisten dışarı bu yazıyı yazan alınmasın hemen genel olarak bir yorum yaptım nokta

Bu hadsizlikle biz değil ama sizin burada fazla barınamayacağınız oldukça aşikar!

arkadaşlar kişisel tartışmalarınızı birbirinize özel mesajlar atarak tartışsanız daha iyi olur. En azından benim konum bildirimin altında olmasın. hem oradan daha rahat kelime ve cümleler seçebilirsiniz kendinize.

haklısın firederick emeğe saygı +1 rep

abi manyakmısınız hala asp kullanıyorsunuz
bir arkadaşımda bu yöntemle yapmıştı forumlarda kullanıyordu

"benim gardropum çok boş" yazmak istedim "benim garum çok boş" yazdı aman ne güzel...

alın size sql injectionun kesin çözümü

SqlParameter[] params = { new SqlParamater("@ID",this.ID) }
Microsoft.SqlHelper.Database.ExecuteNonQuery(SqlString, params);

al bitti

Bilmen gereken şey, bilmediğin şeye dil uzatmak. PHP ye göre zayıf dediğin ASP ile eminim ki senin döktürdüğün PHP işlemlerinden fazlasını yapabilirim. Belki sen 5 satırda çözersin ben 25 satırda ama emin ol ne yapıyorsan fazlası yapılır. ASP, PHP ye göre çok daha yalın bir dil. Yeni programcılar için bir başlangıç. vb olması çok daha güzel...

Gelelim gardrop meselesine, function ile drop, select, event, gibi kelimelerin ilk harflerini yada içinden diğer bir harfi html karşılığı olan ascii lere çevireblirsin.

Örneğin;

form = & #070; ORM
document = & #100; ocument
applet = & #065; pplet
script = & #115; cript
object = & #111; bject
embed = & #101; mbed
event = & #101; vent

Gelelim uzayan iş kısmına, zaten düzenli çalışan bir yazılımcıysan mutlaka belirli kütüphaneler oluşturmuş ve bunları kullanımını da gayet iyi biliyorsundur. Yapman gerken tek şey lib klasörü içinde inc.asp ni sayfana include etmek. Böylece bütün kütüphanen gelir... ister baştan kodla ister düzenle. Bana soracak olursan aspyi de biliyorum php yi de. Ama php ye elimi sürmüyorum.

ASP ile SQL İnjection hakkında daha önce bir çok yazı yazdım hatta ferruh mavituna nın blogunda da bununla ilgili bir yorumumda verdiğim fonksiyon muhtemelen oldukça çok kullanılan bir fonksiyon olmuştur. Yine burada Integere değer alan stringler için küçük ama daha gelişmiş bir kontrol vereyim, firederick in kontrolünün biraz daha gelişmişi

id = LoginKontrol(request.QueryString("ID"))

If IsNull(id) or Not IsNumeric(id) or IsEmpty(id) or Not Len(id) > 0 Then Response.Redirect "Default.asp?Hata=001"
Response.end()
End If

Buda tamamiyle hazırlanmış bir fonksiyon

** Silindi - Editor kodu almıyor! **

Umarım karakterlerde bir eksiklik çıkmaz. Saygılar..

select update drop gibi kelimeleri engellemenize gerek yok
sqlde kaçış karakteri (escape character) tek tırnaktır. tek tırnağı aşmadan hiç bi kod çalışmaz.
metin not gibi alanlarda sadece tek tırnağı engelleseniz yeter.

gecikmiş yorum için özür dilerim henüz gördüm.
@fthrkl metin not gibi alanlarda sadece tek tırnak yeterli değil. < ve > lerin de engellenmesi-süzülmesi gerekiyor.

StroProcedure Kullanın..
PArametreleri Gönderin Kafanız Rahat Olsun

/* ses y0k! */

Arkadaşlar kafam çok karıştı. Kimi arkadaş tırnakların engellenmesi sql injectionu da engeller diyor. Kimisi < ve > işaretlerinin de engellenmesi gerekir diyor. Farzedelim ki tırnak ve < ile > işaretlerini engelledik. Peki şu kodlar ne anlama geliyor?

Function kodYok(metin) duzelt = metin duzelt = Replace(duzelt, " ", "") duzelt = Replace(duzelt, "'", "´") kodYok = duzelt
End Function

Zaten < ve > işaretlerini engellememiş miydik? Tekrar "< script" karakterini neden engelliyoruz? Başında < işareti var zaten.

Ben mi yanlış biliyorum? Bilgilendirirseniz sevinirim.

Edit: @ardabalkan arkadaştan aldığım kodlar eklediğimde filtreleniyor. Düzgün çıkmıyor.

Evet, yukarıda

Function kodYok(metin) duzelt = Trim(metin) duzelt = Replace(duzelt, "<", "") duzelt = Replace(duzelt, ">", "") duzelt = Replace(duzelt, ";", ",") duzelt = Replace(duzelt, "SELECT", "") duzelt = Replace(duzelt, "DROP", "") duzelt = Replace(duzelt, "INSERT", "") duzelt = Replace(duzelt, "UPDATE", "") duzelt = Replace(duzelt, "DELETE", "") duzelt = Replace(duzelt, "FROM", "") duzelt = Replace(duzelt, """", "'") duzelt = Replace(duzelt, "'", "'") kodYok = duzelt
End Function

Bu fonksiyon benim işimi görüyor, ama güvenlik duvarlarınızı aşmayı kafaya koymuş birisi, bunu yapmanın yolunu eninde sonunda bulacaktır :) Bunlar "yeni başlayanlar" ı engelleyebilecek yöntemler.

Yukarıda kodlar yamulmuş, tekrar:


Function kodYok(metin) duzelt = Trim(metin) duzelt = Replace(duzelt, "<", "") duzelt = Replace(duzelt, ">", "") duzelt = Replace(duzelt, ";", ",") duzelt = Replace(duzelt, "SELECT", "") duzelt = Replace(duzelt, "DROP", "") duzelt = Replace(duzelt, "INSERT", "") duzelt = Replace(duzelt, "UPDATE", "") duzelt = Replace(duzelt, "DELETE", "") duzelt = Replace(duzelt, "FROM", "") duzelt = Replace(duzelt, "select", "") duzelt = Replace(duzelt, "drop", "") duzelt = Replace(duzelt, "insert", "") duzelt = Replace(duzelt, "update", "") duzelt = Replace(duzelt, "delete", "") duzelt = Replace(duzelt, "from", "") duzelt = Replace(duzelt, """", "''") duzelt = Replace(duzelt, "'", "'") kodYok = duzelt
End Function

üye olunpillinetwork sitelerine yorum ekleyebilmek ve daha fazlası için, üye olun ya da giriş yapın.

İlgili Yazılar

Bu yazıyı rapor et. Kural dışı içeriğe rastladığınızda editörlerimize rapor ederek müdahale edilmesini sağlayabilirsiniz. (Hangi durumlarda rapor edebilirim?)

Bu site

Nokta ve pilli ortak yapımı olan kodaman.org hep birlikte içerik üretip gelirini yazarları ile paylaştığımız kolektif bir kod yazarları blogudur. Siz de katılabilirsiniz.

pilliilan

son yorumlar

arama

pillinetwork