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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
önceki yazı C# - Dinamik DLL İşlemleri |
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_idnumarasiCmd.Execute()
Set Cmd = Nothing
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
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
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?
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
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.
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
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
pillinetwork sitelerine yorum ekleyebilmek ve daha fazlası için, üye olun ya da giriş yapın.
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.