Veilige webcode schrijven

Pagina: 1
Acties:

  • Johannes Verelst
  • Registratie: Februari 2001
  • Laatst online: 14-11-2022
Hey,

Ik vind dat dit eigenlijk in de FAQ moet, maar ik ben ook niet omnipotent dus ik hoop dat er rond dit punt een beetje discussie ontstaat.

Een tijdje geleden heb ik op eigen initiatief (achtergrond: ik ben een 21 jarige student die part-time bij een groot internationaal op de E-commerce afdeling werkte) op m'n werk gevraagd hoe het met security zat, en dat bracht eigenlijk alleen een hoop ge-'euh' voort. Ik heb toen maar eens de code (ASP, een paar honderd files, echt behoorlijk wat dus) gescand op problemen, en daar kwam ik de volgende problemen tegen:

- SQL injection. Er staat vrij uitgebreid op www.sqlsecurity.com beschreven wat dit is, maar ik zal het even herhalen. Stel, ik heb een webshop waar iemand kan zoeken op artikelen. Iemand kan dan uit een drop-down box kiezen op wat voor product, hierdoor wordt er een getal gepost naar mijn zoekpagina. Ik maak dan de volgende query:

query = "SELECT * FROM Catalog WHERE productcat= " & Request.Item("catalogid")

Voor de meeste mensen zal het gelijk duidelijk zijn: dit kan natuurlijk mis gaan. Als iemand niet netjes de drop-down box gebruikt maar zelf iets in de URL intikt (let er op dat het met POST forms ook werkt, kost voor de aanvaller maar ietsje meer moeite) dan kan het vervelende gevolgen hebben. Stel dat er ingetikt wordt: '3 DROP CATALOG' dan is mijn catalogus weg (ik ga nu even uit van MS SQL server, maar vergelijkbare constructies zijn voor alle SQL servers mogelijk).

Regel 1: vertrouw NIETS (en dan dus ook echt NIETS) wat van de user komt. Dus geen variabelen, geen cookie-waarden, geen headers, nada!

- Directory traversal
Lijkt een beetje op het vorige: in de code die ik doorkeek werden er wel eens files geopend die afhingen van user-input, maar ook hier werd niet goed gelet op onverwachte tekens. Een voorbeeld:

attachment = "C:\attachments\" + Request.Item("attachmentid")

Gaat overduidelijk fout. Dus hieruit volgt regel 2:
vertrouw NIETS (en dan dus ook echt NIETS) wat van de user komt. Dus geen variabelen, geen cookie-waarden, geen headers, nada!

Dit waren dus twee implementatieproblemen, maar ook voor architecten valt er veel te leren. Bovenstaande, en een hoop andere, dingen staan trouwen ook op de Open Web Application Security Project site: www.owasp.org (nee, ik heb niets met dit project te maken, maar ik heb wel info er van gebruikt bij het testen van de applicatie)

Ik hoop dat hier een FAQ itempje van gemaakt kan worden, zodat er meer mensen op het schrijven van veilige code gaan letten.

Ohja, ik had uiteindelijk in meer dan 20 pagina's meer dan 100 problemen gevonden, dus een cracker had 100 mogelijkheden om in systemen in te breken ... :'(

There are no stupid questions, but there are a lot of inquisitive idiots.


  • XTerm
  • Registratie: Juli 2001
  • Laatst online: 10-06-2025
Misschien niet echt een "mooie" oplossing, maar een klein stukje code dat binnenkomende tekst op verdachte stukjes scant en de pakketjes dropt ?

  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Je hebt groot gelijk, maar veiligheid is wat ons allen aangaat en een goede web-ontwikkelaar staat dergelijke dingen niet toe :) Maar hier zijn al meer topics over geweest.. Ik zie het nut van een faq topic dan ook niet echt.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Iedereen maakt fouten, en je kunt ook niet overal opletten. Het is gewoon slim om iemand anders es naar jou code te laten kijken, vooral als het om belangrijke code gaat.

Maar ja, die gene moet er wel zijn.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Johannes Verelst
  • Registratie: Februari 2001
  • Laatst online: 14-11-2022
Ik vrees dat er hier op het forum meer beginnende programmeurs in de FAQ kijken dan ervaren webontwikkelaars. Zoals ik al zei: ik kwam dit soort code tegen in software van een groot internationaal bedrijf. Er lopen natuurlijk een aantal mensen rond die nooit een fatsoenlijke informaticaopleiding hebben gehad, maar ook mensen met hoge opleiding maken deze fouten. Ikzelf deed het, voordat ik me echt in security ging interesseren, ook.

Er zijn maar twee manieren op lekke applicaties te voorkomen: interesse in security, of het erin hameren :) Ik heb op m'n werk het laatste geprobeerd, dus ik hoop dat het een beetje is blijven hangen ...

There are no stupid questions, but there are a lot of inquisitive idiots.


  • razor-x
  • Registratie: Februari 2001
  • Laatst online: 05-06 07:37
tada :)
[topic=294247/1/999]

  • _JGC_
  • Registratie: Juli 2000
  • Nu online
password check is ook zoiets:

select count(user) from usertable where name = $name and pass = $pass

vul je als pass in: hallo or 1=1

Als je vervolgens kijkt of die count 0 was om em er niet in te laten, is ie dus niet 0, maar het aantal gebruikers in je table.

Ik doe het dan met een getpasswd($user) functie, die het password voor de user ophaalt, hier een MD5 op doet, en vervolgens kan je het resultaat vergelijken met de MD5 die je in de gebruiker z'n koek hebt gezet :)

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 15-04 15:52
hmm toevallig dat er een toppic hier overstaat nu aangezien mijn webpage gehacked is vorige nacht...

Weet niet door wie en hoe en er is ook geen mailtje met de "bug" verstuurd.

Mischien dat de "hacker" ook op deze manier binnen is gekomen :?

Dit is dan ook een oproep aan alle meehelpende geesten die mischien eens zouden willen kijken hoe deze persoon iets op mijn pagina kon posten...

je kunt me mailen op 4of9@usa.net

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Op zaterdag 15 december 2001 23:22 schreef Wizard_of_OS het volgende:
Ik vrees dat er hier op het forum meer beginnende programmeurs in de FAQ kijken dan ervaren webontwikkelaars. Zoals ik al zei: ik kwam dit soort code tegen in software van een groot internationaal bedrijf. Er lopen natuurlijk een aantal mensen rond die nooit een fatsoenlijke informaticaopleiding hebben gehad, maar ook mensen met hoge opleiding maken deze fouten. Ikzelf deed het, voordat ik me echt in security ging interesseren, ook.

Er zijn maar twee manieren op lekke applicaties te voorkomen: interesse in security, of het erin hameren :) Ik heb op m'n werk het laatste geprobeerd, dus ik hoop dat het een beetje is blijven hangen ...
Eigenlijk ben ik al lang blij als er iemand (naast D2k) in de faq kijkt ;). en het is idd triest hoe het niveau van sommige programmeurs en/of bedrijven is (i know)

maar ik vindt dat nog geen reden om er een faq van te maken.

Code review is BTW erg belangrijk, en het niet trusten van gebruikers ook. Best practices zijn bij de meeste programmeurs wel bekend. En newbie's zouden er op hun minst over na moeten denken..

Ik waardeer je inbreng zeer begrijp me niet verkeerd, maar ik vind het geen faq waard :)

  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Op zaterdag 15 december 2001 23:28 schreef _JGC_ het volgende:
password check is ook zoiets:

select count(user) from usertable where name = $name and pass = $pass

vul je als pass in: hallo or 1=1

Als je vervolgens kijkt of die count 0 was om em er niet in te laten, is ie dus niet 0, maar het aantal gebruikers in je table.

Ik doe het dan met een getpasswd($user) functie, die het password voor de user ophaalt, hier een MD5 op doet, en vervolgens kan je het resultaat vergelijken met de MD5 die je in de gebruiker z'n koek hebt gezet :)
password plaintext in de database opslaan is _not done_
beter kun je het wachtwoord md5-en en dan vergelijken met de invoer (hoewel md5 daar niet voor bedoeld is maar dat is weer een ander verhaal)

  • dusty
  • Registratie: Mei 2000
  • Laatst online: 21-02 00:06

dusty

Celebrate Life!

Op zaterdag 15 december 2001 23:22 schreef Wizard_of_OS het volgende:
[...]Er zijn maar twee manieren op lekke applicaties te voorkomen: interesse in security, of het erin hameren :) Ik heb op m'n werk het laatste geprobeerd, dus ik hoop dat het een beetje is blijven hangen ...
Helaas werkt de laatste maar een bepaalde tijd voordat men het weer vergeet. (uit ervaring.)

Back In Black!
"Je moet haar alleen aan de ketting leggen" - MueR


  • Johannes Verelst
  • Registratie: Februari 2001
  • Laatst online: 14-11-2022
Op zaterdag 15 december 2001 23:31 schreef wasigh het volgende:

[..]

password plaintext in de database opslaan is _not done_
beter kun je het wachtwoord md5-en en dan vergelijken met de invoer (hoewel md5 daar niet voor bedoeld is maar dat is weer een ander verhaal)
MD5 is wel een cryptografisch sterk hash-algoritme, dus dat zit wel goed hoor :)

There are no stupid questions, but there are a lot of inquisitive idiots.


  • _JGC_
  • Registratie: Juli 2000
  • Nu online
MD5 is zeker geschikt, ik sla nu alles nog op als plain text en gebruik MD5 over beide om het te controleren (beetje onnozel om ook plain text als cookie op te slaan |:( )

Ik ga binnenkort mn forum gedag zeggen (UB2K PE 2.11, allang vertrokken dat bedrijf), ben ik er achter gekomen dat die crypt functies gebruikten op de account db. Ikke blij dat ik alles nog in plain text in mn dbase heb staan: gewoon met crypt (is dus DES) alles weer terug in de database zetten en voortaan mn koeken wat aanpassen zodat dit gaat werken.

  • Johannes Verelst
  • Registratie: Februari 2001
  • Laatst online: 14-11-2022
Op zaterdag 15 december 2001 23:29 schreef wasigh het volgende:

[..]

Eigenlijk ben ik al lang blij als er iemand (naast D2k) in de faq kijkt ;). en het is idd triest hoe het niveau van sommige programmeurs en/of bedrijven is (i know)

maar ik vindt dat nog geen reden om er een faq van te maken.

Code review is BTW erg belangrijk, en het niet trusten van gebruikers ook. Best practices zijn bij de meeste programmeurs wel bekend. En newbie's zouden er op hun minst over na moeten denken..

Ik waardeer je inbreng zeer begrijp me niet verkeerd, maar ik vind het geen faq waard :)
Code reviews zijn zeker erg belangrijk, maar het 'niet trusten van gebruikers' zou eigenlijk toch vooraan moeten komen, toch? :-P. Een code review kan alleen een probleem oplossen als de programmeurs weten waar ze naar moeten kijken. De 100+ fouten die ik heb gevonden waren een code-review, maar dat was wel omdat ik wist waar je op moest letten, m'n collega's wisten dat niet.

Ik snap dat dit topic niet in de FAQ terecht komt, dus ik zal niet zeuren ... of ... toch? ;-) Voordat je er een slot op zet: binnen een bedrijf behoren er best-practices te bestaan (dat ze vaak niet goed zijn is een tweede), maar hier komen veel zelf-knutselaars. Mensen die zelf een webshopje bouwen, freelancen, zelf knutselen, etc. Die komen nooit met dit soort informatie in aanraking, met als gevolg dat er massa's lekke sites van de bakker-op-de-hoek.

Programmeurs bij een groot bedrijf hebben waarschijnlijk niets aan deze tips (er van uitgaande dat zij wel goede coding-guidelines hebben), maar mensen die hier komen wel (niets ten nadele van de gemiddelde lezer, als ik niet toevallig in security geintereseerd was geraakt dan had ik het hier ook voor het eerst gelezen).

Ook op universiteiten wordt hier niet genoeg aandacht aan besteed. Ik heb het vak internetprogrammeren gevolgd, daar werd al het bovenstaande tussen neus en lippen door genoemd, er waren nauwelijks 2 sheets aan besteed.

[met galm]
Het is onze taak om zoveel mogelijk mensen duidelijk te maken dat als je code schrijft, je moet weten hoe je dat moet doen. Naast een PHP manual dus een lijst met URL's over het schrijven van veilige code
[/met galm]

:-P okay, nu stop ik :D
(als ik hiermee over een vage lijn ben gegaan mag je hem trashen, maar laat dan het topic open. Ik vind een discussie hierover het belangrijkst)

There are no stupid questions, but there are a lot of inquisitive idiots.


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 15-04 15:52
heb jij niet toevallig mijn site gehacked? ;)

stond wel LAMER bij (zie onder titel) :P

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • Johannes Verelst
  • Registratie: Februari 2001
  • Laatst online: 14-11-2022
Op zondag 16 december 2001 00:32 schreef 4of9 het volgende:
heb jij niet toevallig mijn site gehacked? ;)

stond wel LAMER bij (zie onder titel) :P
Hahahaha, nee, ik ben wel een hacker (in de zin: ik ben iemand die veel van security wil weten maar het nooit in praktijk brengt zonder voorafgaande toestemming), maar geen cracker.

Als je wil kan ik trouwens wel even naar je code kijken om te kijken of er security leaks in zitten (zie m'n profile voor m'n mailadres). Zolang het niet al te gek wordt natuurlijk :)

There are no stupid questions, but there are a lot of inquisitive idiots.


  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

topic gaat niet op slot hoor :)

security is idd belangrijk :) maar daar krijgt iedereen vroef of laat mee te maken.
Je moet gewoon weten waar je mee bezig bent.

(ik ga ook niet aan 220 volt knutselen als ik daar niets vanaf weet)

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 15-04 15:52
thx Wizzard...

Ik mail je nog wel even hierover... Alvast bedankt :)

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


Verwijderd

ja, op mijn school word dus wel wat met servlets gedaan, maar ook niet met security. en ik ben dus op een gegeven moment bezig gegaan met een down- en upload servlet voor een file browser. dit omdat applets geen rechten hebben. maar het probleem bij mij is, er is wel over nagedacht maar een denk fout kan al snel leiden tot een leak :-( zonder dat ik dat zelf door heb !
gelukkig heeft de String.equals in java geen last van de voorgenoemde extra toevoegingen aan je database query.

  • [ti]
  • Registratie: Februari 2000
  • Niet online
Om even op dat SQL query injection verhaal terug te komen (en ik ben zat dus alst niet klopt danwas dat de alcohol).

Als je perse de username en password combinatie wilt koppelen in de query (username = '$username' and password =
'$password'), kun je het beste altijd daarna nog handmatig het terug gegeven password vanuit je resultset checken als wat is ingegeven vanuit het form. Op die manier kan iemand nooit ' or 1=1 ' oid opgeven als pwd/username want de resultset klopt niet met wat er in het form is opgegeven.

Het voorbeeld wat Wizard_of_OS geeft werkt volgens mij niet met sql server/mysql - vanuit een connectie met asp/php (odbc of native) kan afaik maar 1 query uitgevoerd worden. Meerdere queries vanuit 1 execute gaan fout.

Bij [topic=294247/1/999] staan nog wat andere voorbeeldjes (die ook op andere talen meer of min van toepassing zijn)

  • Johannes Verelst
  • Registratie: Februari 2001
  • Laatst online: 14-11-2022
Op zondag 16 december 2001 06:27 schreef [ti] het volgende:
Om even op dat SQL query injection verhaal terug te komen (en ik ben zat dus alst niet klopt danwas dat de alcohol).

Als je perse de username en password combinatie wilt koppelen in de query (username = '$username' and password =
'$password'), kun je het beste altijd daarna nog handmatig het terug gegeven password vanuit je resultset checken als wat is ingegeven vanuit het form. Op die manier kan iemand nooit ' or 1=1 ' oid opgeven als pwd/username want de resultset klopt niet met wat er in het form is opgegeven.
Achteraf checken of een teruggegeven waarde goed is is dus absoluut niet genoeg. De rottigheid is al uitgehaald voordat je stukje checking-code aangeroepen wordt, dus je moet altijd VOORDAT je dingen in een SQL query stopt zeker weten dat die query precies wordt wat jij wil. Dat houdt in:
- voor strings: escape alle quotes
- voor integers/doubles/etc: casten zodat evt. tekst erachter door de mand valt
Het voorbeeld wat Wizard_of_OS geeft werkt volgens mij niet met sql server/mysql - vanuit een connectie met asp/php (odbc of native) kan afaik maar 1 query uitgevoerd worden. Meerdere queries vanuit 1 execute gaan fout.

Bij [topic=294247/1/999] staan nog wat andere voorbeeldjes (die ook op andere talen meer of min van toepassing zijn)
Het voorbeeld dat ik gaf gaat wel goed (zelf getest), vanuit het cracker oogpunt. Er worden inderdaad twee queries uitgevoerd, dus je krijg twee resultsets terug, iets waar je script misschien niet tegen kan. Voor de hacker niet erg, want die is nu al binnen (op het moment dat de tweede query uitgevoerd was heeft hij een user aan laten maken en een mailtje gestuuurd ofzo).

Het uitvoeren van twee queries gaat trouwens alleen met MS SQL server goed, als je MySQL gebruikt zijn er weer andere truucs.

There are no stupid questions, but there are a lot of inquisitive idiots.


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Wat ook niet onbelangrijk is, is om de web-app onder de juiste rechten te laten draaien. Wat moet een web-app over het algemeen met een gebruikersrecht als drop table of alter table. In je admin sectie kun je een db-gebruiker met meer rechten instellen. Maar verder?

Wat betreft dat user name en wachtwoord verhaal. Maak een hash van de gebruikers naam + wachtwoord en zoek die in combinatie met de gebruikersnaam op.

En het is natuurlijk debiel om je sql query alleen op waar of onwaar te checken. ALTIJD checken of de te authoriseren gebruiker ook daadwerkelijk die ene rij in je resultset is. Afdwingen dat de gebruikers naam alfanummeriek moet zijn (cijfers en letters) voordat het naar de db gestuurd wordt, helpt ook al een hele hoop.

  • [ti]
  • Registratie: Februari 2000
  • Niet online
Wizard_of_OS: Jah uiteraard moet je de boel wel escapen e.d. (dat had ik er idd beter even bij moeten zeggen), maar daarentegen ook daarna nog je result set checken op wat je terug krijgt (ivm eventuele andere onvoorziene problemen die de query stuk hebben gemaakt ofzo).
Pagina: 1