[ PavleBgd @ 15.08.2005. 20:54 ] @
Koliko je ovaj kod kojim se proverava form data, query string ili session
promenljiva koristan za zaustavljanje SQL injection napada?
Da li moze da se nadje neki "workaround" za ovaj problem?

Code:

'Proverava da li maliciozan kod u upitu, znakovi ', \, &, #
Function OsnovnaProvera(strText)

    OsnovnaProvera = False
    intLenght = Len(strText)

    For I=1 To intLenght
        strChar = Mid(strText, I, 1)
        
        If(strChar = "'" OR strChar = "\" OR strChar = "&" OR strChar = "#") Then
            Response.Write "Otkriveno je da ste zadali zabranjene karaktere u upitu."
            OsnovnaProvera = False
            Exit Function
        End If

    Next

    'string je ok
    OsnovnaProvera = True

End Function

http://www.bilosta.co.yu/unos.asp?Name=proba

strName = Request.QueryString("Name")

If NOT OsnovnaProvera(strName) then
Response.End
End if


To pitam zbog toga sto pisem svoju ASP aplikaciju ali nisam siguran kako bi sve
korisnik (ajde ako moram da upotrebim i izraz "haker") mogao da zaobidje
ovakvu validaciju?

[Shadowed: dodati [code] tagovi]

[Ovu poruku je menjao Shadowed dana 16.08.2005. u 18:37 GMT+1]
[ negyxo @ 16.08.2005. 09:21 ] @
Cemu sve to? Otkud to da postoje zabranjeni karakteri za SQL? (dobro mozda za neki levi DB...)
[ PavleBgd @ 16.08.2005. 09:40 ] @
Svaka DB i web aplikacija moze biti ranjiva na SQL injection napad - pretrazi malo na googleu sta o tome pise.
[ negyxo @ 16.08.2005. 12:43 ] @
Ispravka.
Svaka losa DB i WEB aplikacija.
SQL injection je dosta predvidljiv. Ja sam jos davno (dobro ne tako davno) kad sam radio import nekih podataka u access iz clipera, odnosno dBase (dbf), imao taj problem. Program koji sam radio bio je u VB6 pisan i naravno umesto parametara ja koristio obicno spajanje stringova. Pa tako kada je korisnik upisao u search za karaktere @`^[] (koji su naravno u cliperu korisceni kao nasa slova) ja sam samo imao probleme, pa sam naravno pribegao funkcijama za proveru stringa. Nesto slicno sto i ti sad radis. Naravno sve je to nepotrebno. Doduse kao sto rekoh, dosta zavisi i do DB-a. Bitno je samo da radis preko parametara i taj problem nesataje.

[ Shadowed @ 16.08.2005. 18:31 ] @
Taj kod se da znacajno optimizovati.
Zameni deo:
Code:

For I=1 To intLenght
        strChar = Mid(strText, I, 1)
        
        If(strChar = "'" OR strChar = "\" OR strChar = "&" OR strChar = "#") Then
            Response.Write "Otkriveno je da ste zadali zabranjene karaktere u upitu."
            OsnovnaProvera = False
            Exit Function
        End If

    Next

sa:
Code:

If(inStr(strText, "'") + inStr(strText, "\") + inStr(strText, "#") = 0 Then
            Response.Write "Otkriveno je da ste zadali zabranjene karaktere u upitu."
            OsnovnaProvera = False
            Exit Function
        End If


E sad, ne znaci da ce te ovo sasvim zastititi. Zamisli da imas nesto kao:
Code:
"SELECT * FROM SomeTable WHERE userID=" & txtUser.Text)


UserID je broj.
I naravno, propustis txtUser.Text kroz tu proveru. Neko uzme i upise 23 OR 0=0.

[Ovu poruku je menjao Shadowed dana 17.08.2005. u 17:37 GMT+1]
[ Albus @ 17.08.2005. 09:39 ] @
Nisam bas shvatio zasto je taj kod 'znacajno optimizovan'
Uz to, da li je sintakticki ispravan?

Uputite me da li postoji tema o tome kako napraviti 'minimalnog usera' na SQL serveru (user koji nista ne moze van svoje baze, a ni u svojoj ne moze da dropuje tabele....)

Mislim da takav user (web) bi ipak imao neka prava na masteru koja bi mogao da (zlo)upotrebi.

Ako vec injectuje neka to cini kontrolisano.
[ PavleBgd @ 17.08.2005. 14:41 ] @
Hvala Vam puno na odgovorima, doradio sam malo funkciju i imenovao sam je drugcije. Baza je Access i koliko ja znam mogu da se koriste i queryji iz Accesa direktno iz ASP-a kroz parametre. Jedno pitanje, zar ne bi trebalo da se izvrsi validacija i parametara pre poziva query-ja, ne zbog SQL injectiona koliko zbog toga da bi program javio da je korisnik uneo nesta sto ne bi trebao, greskom ili sa namerom?

Code:
Function DaLiImaNeDozvoljenihKaraktera(strText)
Dim strKarakteri(15) 
'SQL escape sekvenca
strKarakteri(1) = "'"
strKarakteri(2) = "%"
strKarakteri(3) = "--"
strKarakteri(4) = "\"
strKarakteri(5) = "*"
'zastita od upita
strKarakteri(6) = "SELECT"
strKarakteri(7) = "INSERT"
strKarakteri(8) = "DELETE"
strKarakteri(9) = "UPDATE"
strKarakteri(10) = "DROP"
'html
strKarakteri(11) = "&"
strKarakteri(12) = "#"
'unos html koda
strKarakteri(13) = ">"
strKarakteri(14) = "<"

'Svaki string u sebi potencijalno ima ne dozvoljene karaktere
DaLiImaNeDozvoljenihKaraktera = True

    For I=1 To 14
        If (InStr(strText, strKarakteri(7), VBTextCompare) > 0) Then
            Response.Write "Nije dozvoljeno koristiti specijalne karaktere u upitu."
            DaLiImaNeDozvoljenihKaraktera = True
            Exit Function
        End If
    Next
DaLiImaNeDozvoljenihKaraktera = False
End Function

'Provera da li je broj, veci od nule
Function OsnovnaProvera(strText)

OsnovnaProvera = False

If (DaLiImaNeDozvoljenihKaraktera(strText)) then
    OsnovnaProvera = False
    Exit Function
End if


End Function


Nemam resenje za onaj problem koji je spomenuo @Shadowed a to je spornost koriscenja "OR" u podacima koje je korisnik POST-ovao iz html forme...

[Ovu poruku je menjao Shadowed dana 17.08.2005. u 17:39 GMT+1]
[ PavleBgd @ 17.08.2005. 16:32 ] @
Evo ga jedan interesantan dokument verujem da ce biti od koristi

http://www.spidynamics.com/papers/SQLInjectionWhitePaper.pdf
[ Shadowed @ 17.08.2005. 16:35 ] @
Izvinjavam se za onaj kod. Nesto sam zeznuo pa je obrisan deo. Idem da ispravim.

Zamolio bih korisnike da koriste [code] tagove.

[Ovu poruku je menjao Shadowed dana 17.08.2005. u 17:47 GMT+1]
[ PavleBgd @ 17.08.2005. 17:22 ] @
Ignorisite funkciju OsnovnaProvera u ovoj zadnjoj verziji koda koji sam poslao, hvala na razumevanju.
[ Albus @ 18.08.2005. 08:26 ] @
Fino napisan kod...

Mozda ne bi bilo lose da se umesto response.write "Nedozvoljeni karakteri" koristi nesto tipa err.raise(404) - nisam siguran za sintaksu.

Evo zasto: razni vulnerabiliti skeneri bi mozda ono prvo videli kao possible sql-injecton vulnerability te bi se haker malo potrudio oko sajta.

Ispravite me ako gresim.

Naravno - koristiti kastomizovanu stranu za 404 da posetilac ne bi pomislio da je pukao sajt ako greskom nesto ukuca. Kad smo kod te strane:
DA LI MOGU KOMPLETAN URL DA POSALJEM SEBI NA MAIL ?
Ako nista drugo da na toj kastom strani prihvatim promenljivu i posaljem sebi na mail zajedno sa vremenom i IP adresom napadaca ?

Ako sam na dobrom putu a nisam neki koder, dajte predloge kastom error strane...
[ PavleBgd @ 18.08.2005. 14:02 ] @
To je interesantna ideja, mogao bi da se upise string koji nije prosao validaciju i IP adresa napadaca u neki log fajl, ne vidim zasto bi to bio problem.
Dodao sam jos nekoliko ispravki u kod:

Code:

Function DaLiImaNeDozvoljenihKaraktera(strText)
Dim strKarakteri(16) 
'SQL escape sekvenca
strKarakteri(1) = "'"
strKarakteri(2) = "%"
strKarakteri(3) = "--"
strKarakteri(4) = "\"
strKarakteri(5) = "*"
'zastita od upita
strKarakteri(6) = "SELECT"
strKarakteri(7) = "INSERT"
strKarakteri(8) = "DELETE"
strKarakteri(9) = "UPDATE"
strKarakteri(10) = "DROP"
strKarakteri(11) = "WHERE"
strKarakteri(12) = " OR "
'html
strKarakteri(13) = "&"
strKarakteri(14) = "#"
'unos html koda
strKarakteri(15) = ">"
strKarakteri(16) = "<"

'Svaki string u sebi potencijalno ima ne dozvoljene karaktere
DaLiImaNeDozvoljenihKaraktera = True

    For I=1 To 16
        If (InStr(strText, strKarakteri(I), VBTextCompare) > 0) Then
            Response.Write "Podaci koje ste uneli nisu validni. Nakon ispravke ponovite postupak. Hvala."
            DaLiImaNeDozvoljenihKaraktera = True
            Exit Function
        End If
    Next
DaLiImaNeDozvoljenihKaraktera = False
End Function


Sa ovim kodom bi trebalo porveriti svaku session promenljivu, query ili post data string pre bilo kakve upotrebe u upitima ili parametrima za procedure. Jedino je pitanje gde se napadac moze jos uvuci...
[ Shadowed @ 18.08.2005. 16:08 ] @
Inace za onaj primer koji sam ti dao, proveri samo da li je podatak brojni.
Uvek je bitno da proveris da li tipovi poadtaka odgovaraju, sto zbog ovakvih propusta sto zbog manje mogucnosti pojave bug-ova.
[ Albus @ 19.08.2005. 08:49 ] @
Naveo si % kao zabranjeni karakter.

Neznam da li onda 'space' moze da radi posto ga browser pretvori u %20 ?
Da li su onda neki karakteri visak - tipa '>' sto odgovara %3E

Ako se dozvoli % sta moze sa tim da uradi ? (Da li moze da progura ' select kao %nesto za svaki karakter?)
[ PavleBgd @ 19.08.2005. 15:26 ] @
Neka me neko ispravi ako gresim, ali koliko je meni poznato svaki formatirani string po prijemu na Web server (IIS, Apache...) se vraca u njegov izvorni oblik, npr. "Hello%20ASP%World" postaje "Hello ASP World" i tako se koristi kao promenljiva u ASP-u, PHP-u...

Dodao sam jos nekoliko izmena:

Code:

'********************************************************************
'Osnovna validacija za sve stringove
'********************************************************************
Function DaLiImaNeDozvoljenihKaraktera(strText)
Dim strKarakteri(24) 
'SQL escape sekvenca
strKarakteri(1) = "'"
strKarakteri(2) = "%"
strKarakteri(3) = "--"
strKarakteri(4) = "\"
strKarakteri(5) = "*"
'zastita od upita
strKarakteri(6) = "SELECT"
strKarakteri(7) = "INSERT"
strKarakteri(8) = "DELETE"
strKarakteri(9) = "UPDATE"
strKarakteri(10) = "WHERE"
strKarakteri(11) = "ALTER"
strKarakteri(12) = " OR "
'SQL sistemske procedure i komande
strKarakteri(13) = "xp_"
strKarakteri(14) = "sp_"
strKarakteri(15) = "cmdshell"
strKarakteri(16) = "makewebtask"
'Access sistemski objekti
strKarakteri(17) = "MSysACEs"
strKarakteri(18) = "MSysObjects"
strKarakteri(19) = "MSysQueries"
strKarakteri(20) = "MSysRelationships"
'html
strKarakteri(21) = "&"
strKarakteri(22) = "#"
'unos html koda
strKarakteri(23) = ">"
strKarakteri(24) = "<"

'Pretpostavka je da strText nije IsNull i da nije IsEmpty, konverzija u string
strText = CStr(strText)

'Svaki string u sebi potencijalno ima ne dozvoljene karaktere
DaLiImaNeDozvoljenihKaraktera = True

    For I=1 To 24
        If (InStr(1,strText, strKarakteri(I), VBTextCompare) > 0) Then
        'If (InStr(1,strText, strKarakteri(7)) > 0) Then
        'If (InStr(1,"salaplaja", strKarakteri(I)) > 0) Then
            Response.Write "Podaci koje ste uneli nisu validni. Nakon ispravke ponovite postupak. Hvala."
            DaLiImaNeDozvoljenihKaraktera = True
            Exit Function
        End If
    Next
DaLiImaNeDozvoljenihKaraktera = False
End Function
[ Albus @ 29.08.2005. 08:06 ] @
Koliko sam uspeo da testiram, kod je OK.

Jedino ne znam gde da ga postavim: hocu da ima Application scope (nesto tipa public function) da ne bi morao da ga kopiram na svaku stranu.

Jel ima neko inteligentnije resenje od pravljenja .dll i ucitavanje istog u global.asa fajlu ?
[ PavleBgd @ 29.08.2005. 11:33 ] @
Ja ga koristim u posebnom asp fajlu, koga onda ukljucujem preko include komande samo na onim asp stranama koje su rizicne:

Code:
<!-- #include file="security.asp" -->


Pozdrav
[ Albus @ 29.08.2005. 14:14 ] @
Ok. Neznam da li je za krpljenje velikog sajta optimalnije resenje praviti .dll ili koristiti include.

Na pocetku svake strane, svaku ulaznu promenjljivu treba provuci kroz funkciju. Gomila if then....

Da li bi moglo da se nekako, kao ulaz provuku svih 10 promenljivih tipa:
DaLiImaNeDozvoljenihKaraktera(promeljiva1, promenljiva2,promenljiva3.....) bez da moram da pravim niz od promenljivih...

U funkciji bi ih spojio u jednu i nju testirao.
Napisao bih ja ali ne znam kako da ovo prevedem iz VB-a u asp:
Code:

Function DaLiImaNeDozvoljenihKaraktera(promenljiva1,optional promenljiva2 as string, optional promenljiva3 as string)
strText=promeljniva1 & promenljiva2 & promenljiva3
' dalje ide tvoja funkcija koja testira strText'


Mozda bi moralo da se rade provere na isMissing....
Ali svakako bi lakse bilo da se radi jedan poziv po strani nego da zovem 10 puta za 10 promenljivih...
Ispravi me ako gresim, i pogledaj za ono optional
[ Albus @ 06.10.2005. 14:54 ] @
Ipak je .dll bolji nego svaki put kad neko dodje na stranu da mu includu-je fajl zato sto ga samo jedamput ucitava u memoriju (kad startuje IIS)
Negde sam procitao (ALI NEZNAM GDE) detaljnije uputstvo o tome sta uraditi u global.asa, kako napraviti taj .dll (sta je u njemu xxxxx a sta yyyy)...
Code:

<OBJECT RUNAT=Server SCOPE=Application ID=xxxxx
    ProgID="yyyy">
</OBJECT>

Ako neko zna napamet neka napise.
[ PavleBgd @ 06.10.2005. 15:41 ] @
Definitivno je bolje resenje (brze i zasticenjije) da kod za proveru kao jos mnogo drugih stvari bude u izvrsnom obliku, kao funkcija ili grupa funkcija, klasa u DLL-u (ISAPI?). Jedino sto ne znam je kako instalirati i korisiti takav DLL kada imate sajt (kao ja) kod hosting provajdera. Trebalo bi pokrenuti registraciju komponenti (RegSvr32.exe) a to ne mogu ja vec provajder? Mozda gresim ali ako neko ima vise infoa bilo bi od pomoci...
[ Shadowed @ 07.10.2005. 21:16 ] @
Provajder ti to nece dozvoliti.
[ PavleBgd @ 08.10.2005. 10:17 ] @
Upravo tako - sem ako nemate svoj Web server(proveravao sam, oko 1000 evra kosta server housing kod vecine provajdera). Do tad ostaje validacija kroz ASP skripte...
[ Albus @ 10.10.2005. 10:38 ] @
Citat:
Shadowed: Provajder ti to nece dozvoliti.


To je druga tema, ali tvoja rupa otvara pristup njegovom sql serveru pa se vrlo lepo mogu videti njegovi useri, objekti u master bazi i sl.

Koliko je to reklama za provajdera ne znam....

Cinjenica je da su oni userima ogranicili prava, ali znam svoj username i svoj pass. Znam ostale username-ove. Ne moram da brute-forcujem njih, mozda su password dodelili na osnovu username-a koji, btw, posetilac sajta ne bi trebalo da vidi ni moj username.
Tu su i linkovani serveri ako ih ima ( a mogu se videti ) .....
Ja sam nabasao na 1452 baze kod jednog stranog provajdera, i nesto vise usernamova (ima ih vise jer su tu i sistemski) samo testirajuci sajt svog prijatelja koji je jedan od tih 1452.
Kazem, to sto oni ne dozvoljavaju, to je njihov problem.
Cinjenica je da mora da se startuje regsvr32....
Ajd, odgovorite, kako na svom, intranet webserveru, da uradim .dll i da ga postavim.

Pavlov kod je sasvim OK, i ono sto bi u n.pr. VB6 trebalo uradim nije nikakva mudrost, ali STA DA KUCAM U GLOBAL.ASA ?
[ vujkev @ 18.11.2005. 01:09 ] @
Čitam ovo i na prvi pogled delovalo je interesantno i da može da se upotrebi, ali onda mi je palo na pamet čemu sve ovo ?? Nigde ne mogu da napišem "Select" kao parametar?Šta ako pišem na engleskom pa mi treba ta reč?
Citat:

"Please select your country"


Pročitao sam par tekstova na ovu temu i koliko sam video sve se svodi na to da se prekine izvršavanje zadate naredbe i da se ubaci svoja kao npr.

Code:

Param1 = request("param1")
db.execute "Select * from tabela1 where ime like '" & Param1 &"'"


i ako se kao param1 posalje
Citat:

bezveze' ; drop table tabela1


nastane haos (možda je glup primer, ali shvatate)

Ali ako se onaj kod malo ispravi da bude ovakav
Code:

Param1 = request("param1")
Param1 = Replace(Param1, "'", "''")
db.execute "Select * from tabela1 where ime like '" & Param1 &"'"


... koliko sam upoznat ovo bi trebalo da radi bez greške šta god da se upiše kao parametar koji se salje na stranicu

ili ako se očekuje broj

Code:

Param1 = request("param1")
if Isnumeric(Param1) = True then
   db.execute "Select * from tabela1 where ID =" & Param1 
end if 


Da li se varam ili je ovo najbolja zaštita od SQL injectiona?


[Ovu poruku je menjao vujkev dana 18.11.2005. u 02:09 GMT+1]

[Ovu poruku je menjao vujkev dana 18.11.2005. u 02:10 GMT+1]
[ Shadowed @ 18.11.2005. 07:12 ] @
Ne postoji najbolja zastita ali je to sto si naveo i sl. potrebno uraditi. Validacija podataka je vrlo pozeljna stvar, nezavisno od SQL injaction-a.
[ branimir.ts @ 18.11.2005. 11:19 ] @
Evo definitivno najbolje konstrukcije u VB u za validaciju numeric inputa, ujedno i zastita od SQL injecta:

for i=1 to Len(Broj)
if Mid(Broj,i,1) < "0" or Mid(Broj,i,1) >"9" then
<<prijavi gresku>>
end if
next

pozdrav
[ Shadowed @ 18.11.2005. 12:09 ] @
Ili IsNumeric(Broj) ;)
[ branimir.ts @ 18.11.2005. 14:19 ] @
DA li si siguran da ce bas u svim slucajevima isNumeric vratiti ispravnu vrednost?
Hmm...ne volim bas toliko da verujem MS ovim Vb funkcijama tipa IsNumeric ,Cstr, VAl itd.

npr. isNumeric("123 ") vraca True, a da li je to zaista tacno?

Ja sam ipak pristalica "defanzivnog programiranja".


Pozdrav



[Ovu poruku je menjao branimir.ts dana 18.11.2005. u 15:33 GMT+1]
[ mladenovicz @ 18.11.2005. 14:40 ] @
Citat:
branimir.ts:
npr. isNumeric("123 ") vraca True, a da li je to zaista tacno?


Citat:
MSDN:

IsNumeric Function

Returns a Boolean value indicating whether an expression can be evaluated as a number.



[Ovu poruku je menjao mladenovicz dana 18.11.2005. u 15:41 GMT+1]
[ branimir.ts @ 18.11.2005. 14:54 ] @
Citat:

Citat:

MSDN:

IsNumeric Function

Returns a Boolean value indicating whether an expression can be evaluated as a number.



Znaci, po njima je i &h20 numeric?
[ mladenovicz @ 18.11.2005. 15:24 ] @
Citat:
branimir.ts: Znaci, po njima je i &h20 numeric?


Ne, nego can be evaluated as a number.
[ branimir.ts @ 18.11.2005. 15:34 ] @
Can be evaluated as ... (SQL Injection String?).

Pozdrav

[Ovu poruku je menjao branimir.ts dana 18.11.2005. u 16:34 GMT+1]