Avatar billede skildpadden Nybegynder
14. december 2007 - 09:20 Der er 15 kommentarer og
2 løsninger

Hvilke tegn skal omkonverteres/fjerns for at undgå sql-injection?

Hvilke tegn skal omkonverteres/fjerns for at undgå sql-injection?
Avatar billede skildpadden Nybegynder
14. december 2007 - 09:21 #1
*Der skulle selvfølgelig stå "fjernes" - ikke "fjerns" :)
Avatar billede softspot Forsker
14. december 2007 - 09:30 #2
Jeg vil ikke påstå at det er det endegyldige svar, men typisk er det via strengværdier du vil kunne opleve forsøg på SQL-injections, så derfor er det som udgangspunkt apostroffer (') der skal fjernes...
Avatar billede mitbrugernavn Praktikant
14. december 2007 - 09:34 #3
strtekst = hej med dig ' julemanden siger "hej hej"

strtekst = replace(strtekst,"'","''")
strtekst = replace(strtekst,""","""")

så er strtekst klar til sql
Avatar billede softspot Forsker
14. december 2007 - 09:56 #4
Jeg vil hellere anbefale dig at undersøge Command-objektet til parameteriserede SQL-sætninger, for det giver dig en god sikkerhed for at injections ikke kan udføres.

Eksempel:

dim id
id = 1

dim cmd, rs

set cmd = Server.CreateObject("ADODB.Command")
set cmd.ActiveConnection = conn  ' conn er dit åbne connectionobjekt
cmd.CommandType = adCmdText
cmd.CommandText = "SELECT * FROM tabel1 WHERE id = ?"
cmd.Parameters.Append cmd.CreateParameter("@id", adInteger, adParamInput, 4, id)
set rs = cmd.Execute()
' ... og så hvad du ellers ville have gjort med dine data fra tabel1


Det er umiddelbart lidt mere omstændigt, men noget af det kan pakkes ind i en eller flere funktioner (f.eks. oprettelsen af commandobjektet og oprettelsen af parametre), så det bliver lidt lettere at have med at gøre. Hvis du vil vide mere om dette emne kan du jo sige til, så kan vi da debatere det lidt... :-)
Avatar billede skildpadden Nybegynder
14. december 2007 - 11:30 #5
softspot: Er sql injection umuligt hvis man bruger dit eksempel?
Avatar billede softspot Forsker
14. december 2007 - 11:56 #6
Som nævnt tidligere, så er jeg ikke ekspert på SQL-injections, men den mest kendte metode til injections er at afslutte en streng og så lave noget SQL efter dette, som kan være mere eller mindre skadeligt for din database. Dette er i det mindste ikke muligt med Command-objektet ovenfor, da strengparametre af Command-objektet behandles som sådan, hvilket betyder at apostroffer blot bliver en naturlig del af parameterværdien og ikke som i strengsammensætningsscenariet en del af den samlede SQL-sætning.

Hvis man lige sætter sin fantasi lidt i spil kunne man forestille sig at en bruger forsøgt at indtaste flg. tekst i et felt (lad os kalde det feltet):

"'; DROP DATABASE;"

og det kunne jo være en katastrofe hvis den blev indsat i flg. SQL:

sql = "SELECT * FROM tabel1 WHERE felt = '" & feltet & "'"

Det ville så resultere i flg. SQL-sætning(er):

SELECT * FROM tabel1 WHERE felt = ''; DROP DATABASE;

Det er muligt at syntaksen for at slette en database er lidt anderledes, men idéen er vist tydelig nok.

Dette princip ville fungere på en SQL Server, hvorimod jeg er lidt mere usikker på om det ville gå i en Access-database (her ville siden højst sandsynligt ende med en fejl der fortæller en hacker lidt mere om din databases layout og måske endda placering).

Nu siger du (og mange andre) nok: "Jamen, det problem er jo løst hvis jeg gør som mitbrugernavn (og tusinde andre før ham/hende her på sitet)". Jeg synes dog det har sin berettigelse. Dels er det rarere at bruge et command-objekt, fordi det er mere i tråd med den COM-måde hvorpå ASP-objekter i øvrigt bruges, dels giver det nogle fordele i de tilfælde, hvor du skal lave batchopdateringer, da du kan genbruge samme Command-objekt og blot tildele nye parametre for hvert kald. Dette giver et performance-boost ifht. strengsammensætningsmotoden, hvor strengen skal sammensættes hver gang.

Desuden har Command-metoden en statisk kompleksitet, hvor strengsammensætningsmetoden har en tendens til at blive uoverskuelig, fordi der sprøjtes rundt med apostroffer, anførselstegn, ampersand'er og hvad har vi! :-)
Avatar billede pidgeot Nybegynder
14. december 2007 - 12:02 #7
Brug af parameters gør at SQL'en for-fortolkes, for så at vente på at modtage værdierne separat. Dermed er SQL injection umulig; uanset hvad der bliver sendt ind, vil det blive opfattet som en værdi, og ikke en del af SQL'en.

Dermed undgår du escaping - det er godt af to grunde:
1) Hvis du selv skriver en escaping funktion, så er det ikke sikkert du er klar over alle de tegn der kan være farlige (eks. NUL bytes)
2) Selvom du bruger databasens egne escaping funktioner, så er det stadig ikke 100% garanteret at der ikke kan opstå SQL injections - både MySQL og PostgreSQL havde for noget tid siden en fejl der escapede forkerte hvis bestemte tegnsæt og byte-komibinationer blev brugt.
Avatar billede skildpadden Nybegynder
14. december 2007 - 12:33 #8
Softspot:
På en side bruger jeg nedenstående - vil du hjælpe mig med at få det til at passe til din løsning?

<%
If isNumeric(intPage) = False Or intPage < 1 Then
    intPage = 1
Else
    intPage = Replace(intPage, "'", "")
    intPage = Replace(intPage, """", "")
    intPage = Replace(intPage, "<", "&lt;")
    intPage = Replace(intPage, ">", "&gt;")
End If


Set ConnObj = Server.CreateObject("ADODB.Connection")
DSN = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:/web/bruger/domain.dk/database/mindatabase.mdb"
ConnObj.Open DSN


strSQL = "SELECT c_brugere5, c_portalniveau1, c_formular1 FROM sikkerhed WHERE sprog = '"& session("sprog") &"' and id = " & CLng(intPage)
Set RstObj = ConnObj.Execute(strSQL)


c_brugere5 = RstObj("c_brugere5")
c_portalniveau1 = RstObj("c_portalniveau1")


RstObj.Close
Set RstObj = Nothing

ConnObj.Close
Set ConnObj = nothing
%>
Avatar billede softspot Forsker
14. december 2007 - 13:05 #9
Ja da!

Jeg skulle mene at flg. burde være Command-udgaven af din:

<%
If isNumeric(intPage) = False Or intPage < 1 Then
    intPage = 1
Else
    intPage = Replace(intPage, "'", "")
    intPage = Replace(intPage, """", "")
    intPage = Replace(intPage, "<", "&lt;")
    intPage = Replace(intPage, ">", "&gt;")
End If


Set ConnObj = Server.CreateObject("ADODB.Connection")
DSN = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:/web/bruger/domain.dk/database/mindatabase.mdb"
ConnObj.Open DSN


strSQL = "SELECT c_brugere5, c_portalniveau1, c_formular1 FROM sikkerhed WHERE sprog = ? and id = ?"

dim cmd, rs

set cmd = Server.CreateObject("ADODB.Command")
set cmd.ActiveConnection = ConnObj  ' conn er dit åbne connectionobjekt
cmd.CommandType = adCmdText
cmd.CommandText = strSQL
cmd.Parameters.Append cmd.CreateParameter("@sprog", adVarChar, adParamInput, 100, session("sprog"))
cmd.Parameters.Append cmd.CreateParameter("@id", adInteger, adParamInput, 4, CLng(intPage))

Set RstObj = cmd.Execute()


c_brugere5 = RstObj("c_brugere5")
c_portalniveau1 = RstObj("c_portalniveau1")


RstObj.Close
Set RstObj = Nothing

ConnObj.Close
Set ConnObj = nothing
%>

Og husk: Selvom du bruger Command-objekter, så er det stadig vigtigt at validere data (typer og indhold) inden du kaster dem efter databasen (ligesom du gør med intPage).
Avatar billede softspot Forsker
14. december 2007 - 13:07 #10
HOVS! Det er nok også en ret god idé at teste om der er noget indhold i det recordset du får tilbage fra databasekaldet. Ret der for flg. kode:

c_brugere5 = RstObj("c_brugere5")
c_portalniveau1 = RstObj("c_portalniveau1")

til dette:

if not RstObj.eof then
  c_brugere5 = RstObj("c_brugere5")
  c_portalniveau1 = RstObj("c_portalniveau1")
end if
Avatar billede skildpadden Nybegynder
14. december 2007 - 13:40 #11
Fungerer det på samme måde med insert og update?
Avatar billede softspot Forsker
14. december 2007 - 13:46 #12
I princippet ja, du vil typisk bare ikke modtage et recordset når du kalder cmd.execute().

Der er naturligvis mange flere muligheder for at bruge Command-objektet, f.eks. muligheden for at oprette returparametre, in-/outputparametre og rene outputparametre fra stored procedures. Dette er dog nok mest relevant når du arbejder med en "rigtig" database (f.eks. SQL Server) ;-)
Avatar billede softspot Forsker
14. december 2007 - 13:50 #13
Jeg kan da anbefale at tage en lille tour rundt i MSDN's referencemanual til ADO: http://msdn2.microsoft.com/en-us/library/ms807498.aspx

Der findes sikkert mange andre gode links, jeg har bare altid fundet de oplysninger jeg havde brug for på MSDN.
Avatar billede skildpadden Nybegynder
23. december 2007 - 21:50 #14
softspot og pidgeot: Tak for hjælpen - vil I lave et svar?
Avatar billede pidgeot Nybegynder
23. december 2007 - 21:57 #15
Jeg sidder over - giv dem til softspot :)
Avatar billede softspot Forsker
24. december 2007 - 00:33 #16
Velbekomme :)
Avatar billede softspot Forsker
25. december 2007 - 14:26 #17
Tak for point :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester