Bekijk Volledige Versie : Input Variabelen Controleren
Hoi Mensen,
Ik zou graag mijn input variabelen uit b.v. een form of $_REUQEST willen
controleren op geldigheid. Wat moet ik precies allemaal doen? en wat
is gangbaar om te doen? Ik kan natuurlijk b.v. de HTML strippen met
strip_tags (voor zover deze niet nodig is.), maar hoever moet ik gaan om
het een beetje veilig te houden? Zijn hier tips voor?
Gerard
Rene Pijlman
24/05/05, 16:35
Wunsch:
>Ik zou graag mijn input variabelen uit b.v. een form of $_REUQEST willen
> controleren op geldigheid. Wat moet ik precies allemaal doen? en wat
>is gangbaar om te doen? Ik kan natuurlijk b.v. de HTML strippen met
>strip_tags (voor zover deze niet nodig is.), maar hoever moet ik gaan om
>het een beetje veilig te houden? Zijn hier tips voor?
Er moet precies in staan wat er in mag staan, niet meer en niet minder.
Een applicatie die schaakzetten accepteert mag bijvoorbeeld "e2-e4" en
"Pg1xf3+" accepteren, en een applicatie die damzetten accepteert "32-28".
Het hangt helemaal van de applicatie af.
En het hangt ervan af wat je met de invoer doet. Gebruikersinvoer in
OS-commando's of SQL-strings stoppen is berucht.
--
René Pijlman
Wat wil jij leren? http://www.leren.nl
Rene Pijlman wrote:
> Wunsch:
>
> En het hangt ervan af wat je met de invoer doet. Gebruikersinvoer in
> OS-commando's of SQL-strings stoppen is berucht.
>
Daar ontkom je in veel gevallen niet aan. Het komt vaak neer op het
opslaan van text-invoer in een database en aangezien een SQL-query uit
normale tekens bestaat is het controleren op tekens die voorkomen in het
alfabet dus een beetje zinloos. Je zou natuurlijk gangbare SQL-commands
(zoals select etc.) kunnen kunnen vervangen met str_replace. Hoe doen
jullie dat?
Gerard
Tjerk Wolterink
24/05/05, 17:05
Wunsch wrote:
> Rene Pijlman wrote:
>
>> Wunsch:
>>
>> En het hangt ervan af wat je met de invoer doet. Gebruikersinvoer in
>> OS-commando's of SQL-strings stoppen is berucht.
>>
> Daar ontkom je in veel gevallen niet aan. Het komt vaak neer op het
> opslaan van text-invoer in een database en aangezien een SQL-query uit
> normale tekens bestaat is het controleren op tekens die voorkomen in het
> alfabet dus een beetje zinloos. Je zou natuurlijk gangbare SQL-commands
> (zoals select etc.) kunnen kunnen vervangen met str_replace. Hoe doen
> jullie dat?
>
> Gerard
Ik heb iets gemaakt dat de sql code genereert, gaat te ver om hier uit te leggen,
en wat input checking betreft heb ik bepaalde datatypes zoals:
TextDataType
PostcodeDataType
EmailDataType
PassWordDataType
(php classes),
deze classes zorgen voor correcte afhandeling van input gegevens door een user.
Je validate gewoon voordat je de sql code in de database stopt.
Als het fout is meld je dit aan de gebruiker.
Tjerk Wolterink wrote:
> Ik heb iets gemaakt dat de sql code genereert, gaat te ver om hier uit
> te leggen,
>
> en wat input checking betreft heb ik bepaalde datatypes zoals:
>
> TextDataType
> PostcodeDataType
> EmailDataType
> PassWordDataType
>
> (php classes),
>
> deze classes zorgen voor correcte afhandeling van input gegevens door
> een user.
>
> Je validate gewoon voordat je de sql code in de database stopt.
> Als het fout is meld je dit aan de gebruiker.
Lijkt me erg handig om het zo op te zetten, inderdaad.
Waar controleer je dan b.v. op in je TextDataType?
behalve of het [a-z0-9,.:;] enz. is?
Hoe voorkom je SQL-injection?
Gerard
Daniel Tryba
24/05/05, 17:15
Wunsch <nospam@svp> wrote:
>> En het hangt ervan af wat je met de invoer doet. Gebruikersinvoer in
>> OS-commando's of SQL-strings stoppen is berucht.
>>
> Daar ontkom je in veel gevallen niet aan. Het komt vaak neer op het
> opslaan van text-invoer in een database en aangezien een SQL-query uit
> normale tekens bestaat is het controleren op tekens die voorkomen in het
> alfabet dus een beetje zinloos. Je zou natuurlijk gangbare SQL-commands
> (zoals select etc.) kunnen kunnen vervangen met str_replace.
Dit is het zelfde als filteren op het woord 'sex'. Een artikel over een
busexcursie naar Lourdes wordt daarmee onterecht gefilterd.
> Hoe doen jullie dat?
Dat is afhankelijk van de database/gebruik. Maar het principe is om
characters die de betekenis van een string kunnen veranderen te escapen.
In een database is dat vaak oa ', voor een shell oa ;. Escapen hiervan
gebeurd vaak door er een \ voor te zetten (zi ebv
http://dev.mysql.com/doc/mysql/en/mysql-real-escape-string.html)
Maar daar is genoeg over te vinden als je even de moeite neemt om te
zoeken. http://nl3.php.net/manual/en/security.database.sql-injection.php
geeft bv enige info.
Rene Pijlman
24/05/05, 17:45
Wunsch:
>Rene Pijlman:
>> En het hangt ervan af wat je met de invoer doet. Gebruikersinvoer in
>> OS-commando's of SQL-strings stoppen is berucht.
>>
>Daar ontkom je in veel gevallen niet aan.
Ik kan mij echte databases herinneren, met een scheiding tussen
querystring en gebonden parameters.
>Je zou natuurlijk gangbare SQL-commands (zoals select etc.) kunnen kunnen
>vervangen met str_replace.
Nee. Je moet hoe dan ook geen query samenstellen met simpele copy&paste
van gebruikersinvoer. Gebruikersinvoer hoort in aparte parameters,
gebonden, gequote, escaped.
Ik gebruik zelf vooral Java/JDBC en PostgreSQL met Python. Daarbij gebruik
je in de applicatie aparte parameters, construeert de database driver de
querystring en die zorgt daarbij voor quoten en escapen. Bij een echte
database als Oracle worden de parameters gebonden, in plaats van in de
querystring geplakt.
--
René Pijlman
Wat wil jij leren? http://www.leren.nl
Rene Pijlman wrote:
>
> Ik gebruik zelf vooral Java/JDBC en PostgreSQL met Python. Daarbij gebruik
> je in de applicatie aparte parameters, construeert de database driver de
> querystring en die zorgt daarbij voor quoten en escapen. Bij een echte
> database als Oracle worden de parameters gebonden, in plaats van in de
> querystring geplakt.
>
Met MySQL onder PHP ben je helaas een stuk beperkter.
Gerard
John Bokma
24/05/05, 20:15
Wunsch wrote:
> alfabet dus een beetje zinloos. Je zou natuurlijk gangbare
> SQL-commands (zoals select etc.) kunnen kunnen vervangen met
> str_replace. Hoe doen jullie dat?
Dat zeker niet.
[1] Stel per variable exact op wat *wel* mag, en in het algemeen: geef
een fout als het hier niet aan voldoet.
B.v. als de gebruiker een getal in moet voeren kan dit zijn:
1 tot 3 cijfers, minimum is 5, maximum is 125
[2] Ga zo min mogelijk ingave zitten repareren. Liefst niet. Als je 3
cijfers vraagt, ga dan b.v. niet alles wat geen cijfer is weggooien,
maar geef een fout. Gebruik defaults alleen als het zinnig is.
Dingen die je evt. kan doen: verwijderen spaties, bij cijfers:
verwijderen voorloopnullen.
In bovenstaande voorbeeld, als iemand azfad invoert, doe dan zeker niet:
geen geldige cijfers, dus ik neem 5 als default.
Tenslotte: ga nooit uit van je form. Een form is altijd te omzeilen. Dus
als je in je form ergens opgeeft dat er maximaal 20 tekens ingegeven
kunnen worden, kijk niet gek op als je er 200 krijgt.
Wat ik vaak doe:
[a] is de variabelen gedefinieerd? Indien dit *moet*, geef ik een fout
als het niet zo is
[b] is de lengte van de waarde acceptabel? Indien nee: fout
[c] is de gegeven waarde acceptabel? Nee: fout.
[d] kan de gegeven waarde een risico betekenen voor verdere verwerking?
zoja: maak dit risico ongedaan.
--
John Voorbeeldscripts in Perl: http://johnbokma.com/perl/
Website design: http://johnbokma.com/websitedesign/
Ervaren Perl / Java programmeur beschikbaar: http://castleamber.com/
Tevreden opdrachtgevers: http://castleamber.com/testimonials.html
Daniel Tryba wrote:
> Dit is het zelfde als filteren op het woord 'sex'. Een artikel over een
> busexcursie naar Lourdes wordt daarmee onterecht gefilterd.
Ja, precies. Je kunt natuurlijk heel ver gaan, maar helemaal sluitend
krijg je het nooit.
> Dat is afhankelijk van de database/gebruik. Maar het principe is om
> characters die de betekenis van een string kunnen veranderen te escapen.
> In een database is dat vaak oa ', voor een shell oa ;. Escapen hiervan
> gebeurd vaak door er een \ voor te zetten (zi ebv
> http://dev.mysql.com/doc/mysql/en/mysql-real-escape-string.html)
>
> Maar daar is genoeg over te vinden als je even de moeite neemt om te
> zoeken. http://nl3.php.net/manual/en/security.database.sql-injection.php
> geeft bv enige info.
>
heee, thankz.. die paginas kon ik nog niet... :)
John Bokma
24/05/05, 20:15
Daniel Tryba wrote:
> Dat is afhankelijk van de database/gebruik. Maar het principe is om
> characters die de betekenis van een string kunnen veranderen te
> escapen. In een database is dat vaak oa ', voor een shell oa ;.
Of prepared statements gebruiken met ? placeholders. Minder geknoei. Ik
begreep dat er zoiets ook (eindelijk?) voor PHP is.
--
John Voorbeeldscripts in Perl: http://johnbokma.com/perl/
Website design: http://johnbokma.com/websitedesign/
Ervaren Perl / Java programmeur beschikbaar: http://castleamber.com/
Tevreden opdrachtgevers: http://castleamber.com/testimonials.html
John Bokma
24/05/05, 20:15
Rene Pijlman wrote:
> Ik gebruik zelf vooral Java/JDBC en PostgreSQL met Python. Daarbij
> gebruik je in de applicatie aparte parameters, construeert de database
> driver de querystring en die zorgt daarbij voor quoten en escapen. Bij
> een echte database als Oracle worden de parameters gebonden, in plaats
> van in de querystring geplakt.
Uhm, dat kan met JDBC (Java) of DBI (Perl) ook, dat binden. Of het echte
werk in de driver plaatsvind, of de database doet er niet zo veel toe.
Ik begreep dat dit voor PHP ook mogelijk zou zijn? Wat een feest moet zijn,
want betekent een einde van stripslashaddquoteescapemagic, toch?
--
John Voorbeeldscripts in Perl: http://johnbokma.com/perl/
Website design: http://johnbokma.com/websitedesign/
Ervaren Perl / Java programmeur beschikbaar: http://castleamber.com/
Tevreden opdrachtgevers: http://castleamber.com/testimonials.html
Tjerk Wolterink
24/05/05, 21:55
Wunsch wrote:
> Tjerk Wolterink wrote:
>
>> Ik heb iets gemaakt dat de sql code genereert, gaat te ver om hier uit
>> te leggen,
>>
>> en wat input checking betreft heb ik bepaalde datatypes zoals:
>>
>> TextDataType
>> PostcodeDataType
>> EmailDataType
>> PassWordDataType
>>
>> (php classes),
>>
>> deze classes zorgen voor correcte afhandeling van input gegevens door
>> een user.
>>
>> Je validate gewoon voordat je de sql code in de database stopt.
>> Als het fout is meld je dit aan de gebruiker.
>
>
> Lijkt me erg handig om het zo op te zetten, inderdaad.
> Waar controleer je dan b.v. op in je TextDataType?
> behalve of het [a-z0-9,.:;] enz. is?
> Hoe voorkom je SQL-injection?
>
> Gerard
Zoiets:
// ff een paar global functies
function format_input($txt) {
if($txt==null) return "NULL";
$txt=trim($txt);
if($txt=="" || $txt==" ") return "NULL";
if(!get_magic_quotes_gpc())
$txt=addslashes($txt);
$txt="'$txt'";
return $txt;
}
function validate_email($text) {
return
eregi("^[0-9a-z]([-_.~]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,4}$", $text);
}
//abstracte klasse
class DataType {
var $type;
function validate($name) {
return true;
}
function sql_format($name) {
global $_POST;
return format_input[$name]
}
}
// specifieke datatype voor bijvoorbeeld e-mail (niet uitgewerkt)
class EmailDataType extends DataType {
function validate($name) {
global $_POST:
return validate_email($name) ? true : "Het ingevulde e-mail adres is ongeldig";
}
}
Tjerk Wolterink
24/05/05, 21:55
Tjerk Wolterink wrote:
> Wunsch wrote:
>
>> Rene Pijlman wrote:
>>
>>> Wunsch:
>>>
>>> En het hangt ervan af wat je met de invoer doet. Gebruikersinvoer in
>>> OS-commando's of SQL-strings stoppen is berucht.
>>>
>> Daar ontkom je in veel gevallen niet aan. Het komt vaak neer op het
>> opslaan van text-invoer in een database en aangezien een SQL-query uit
>> normale tekens bestaat is het controleren op tekens die voorkomen in
>> het alfabet dus een beetje zinloos. Je zou natuurlijk gangbare
>> SQL-commands (zoals select etc.) kunnen kunnen vervangen met
>> str_replace. Hoe doen jullie dat?
>>
>> Gerard
>
>
> Ik heb iets gemaakt dat de sql code genereert, gaat te ver om hier uit
> te leggen,
>
> en wat input checking betreft heb ik bepaalde datatypes zoals:
>
> TextDataType
> PostcodeDataType
> EmailDataType
> PassWordDataType
>
> (php classes),
>
> deze classes zorgen voor correcte afhandeling van input gegevens door
> een user.
>
> Je validate gewoon voordat je de sql code in de database stopt.
> Als het fout is meld je dit aan de gebruiker.
ow deze reactie van mij klopt niet echt met je vraag merk ik nu
Rene Pijlman
24/05/05, 22:45
John Bokma:
>Rene Pijlman:
>> Ik gebruik zelf vooral Java/JDBC en PostgreSQL met Python. Daarbij
>> gebruik je in de applicatie aparte parameters, construeert de database
>> driver de querystring en die zorgt daarbij voor quoten en escapen. Bij
>> een echte database als Oracle worden de parameters gebonden, in plaats
>> van in de querystring geplakt.
>
>Uhm, dat kan met JDBC (Java) of DBI (Perl) ook, dat binden.
Met dat binden bedoelde ik: query en parameter values gescheiden tot in de
database engine. Dit in tegenstelling tot de client-side benadering,
waarbij de parameters 'onder water' in de querystring worden geplakt (met
quoten en escapen, dat wel).
>Of het echte werk in de driver plaatsvind, of de database doet er niet
>zo veel toe.
Voor de veiligheid en functionaliteit van de applicatie niet nee, dat is
waar.
Voor de performance misschien wel. Bij dat echte server-side binden kan
een voorbereide query (geparsed, autorisaties gechecked, execution plan
geoptimaliseerd) namelijk worden hergebruikt met verschillende
parameterwaarden.
--
René Pijlman
Wat wil jij leren? http://www.leren.nl
Tjerk Wolterink wrote:
> ow deze reactie van mij klopt niet echt met je vraag merk ik nu
Je antwoord was niet geheel nutteloos. Het geeft me wel een idee hoe ik
het een beetje structureel kan oplossen.. dussu.. bedankt... :)
Gerard
Tjerk Wolterink wrote:
> Zoiets:
>
> // ff een paar global functies
> function format_input($txt) {
> if($txt==null) return "NULL";
> $txt=trim($txt);
> if($txt=="" || $txt==" ") return "NULL";
> if(!get_magic_quotes_gpc())
> $txt=addslashes($txt);
> $txt="'$txt'";
> return $txt;
> }
>
> function validate_email($text) {
> return
> eregi("^[0-9a-z]([-_.~]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,4}$",
> $text);
> }
>
>
> //abstracte klasse
> class DataType {
> var $type;
>
> function validate($name) {
> return true;
> }
>
> function sql_format($name) {
> global $_POST;
> return format_input[$name]
> }
>
> }
>
> // specifieke datatype voor bijvoorbeeld e-mail (niet uitgewerkt)
> class EmailDataType extends DataType {
>
> function validate($name) {
> global $_POST:
> return validate_email($name) ? true : "Het ingevulde e-mail adres is
> ongeldig";
> }
>
> }
>
heee, bedankt.. ik ga wat dingetjes van je gebruiken.. :)
Gerard
John Bokma
25/05/05, 00:45
Rene Pijlman wrote:
> John Bokma:
>>Rene Pijlman:
>>> Ik gebruik zelf vooral Java/JDBC en PostgreSQL met Python. Daarbij
>>> gebruik je in de applicatie aparte parameters, construeert de
>>> database driver de querystring en die zorgt daarbij voor quoten en
>>> escapen. Bij een echte database als Oracle worden de parameters
>>> gebonden, in plaats van in de querystring geplakt.
>>
>>Uhm, dat kan met JDBC (Java) of DBI (Perl) ook, dat binden.
>
> Met dat binden bedoelde ik: query en parameter values gescheiden tot
> in de database engine. Dit in tegenstelling tot de client-side
> benadering, waarbij de parameters 'onder water' in de querystring
> worden geplakt (met quoten en escapen, dat wel).
Ja, ik gokte dat je dat bedoelde, vandaar:
>>Of het echte werk in de driver plaatsvind, of de database doet er niet
>>zo veel toe.
>
> Voor de veiligheid en functionaliteit van de applicatie niet nee, dat
> is waar.
>
> Voor de performance misschien wel. Bij dat echte server-side binden
> kan een voorbereide query (geparsed, autorisaties gechecked, execution
> plan geoptimaliseerd) namelijk worden hergebruikt met verschillende
> parameterwaarden.
Yup, eens.
Maar ik begreep ooit uit een discussie dat zoiets nu ook middels een
PEAR module in PHP te doen is?
--
John Voorbeeldscripts in Perl: http://johnbokma.com/perl/
Website design: http://johnbokma.com/websitedesign/
Ervaren Perl / Java programmeur beschikbaar: http://castleamber.com/
Tevreden opdrachtgevers: http://castleamber.com/testimonials.html
John Bokma schreef op 24-05-05 20:14:
> Ik begreep dat dit voor PHP ook mogelijk zou zijn? Wat een feest moet zijn,
> want betekent een einde van stripslashaddquoteescapemagic, toch?
Dat zou dan http://pear.php.net/manual/en/package.database.db.php moeten
zijn, gok ik.
Groeten,
Patrick
John Bokma wrote:
> Maar ik begreep ooit uit een discussie dat zoiets nu ook middels een
> PEAR module in PHP te doen is?
Parameter binding zit ook in mysqli onder PHP5, zag ik net.
(mysqli_stmt_bind_param o.a.)
eveneens het escapen van karaters (mysqli_real_escape_string)
tis natuurlijk wel in de driver dan, zal met latere versies van mysql
ook wel in het DBMS kunnen, neem ik aan. versie 5 ofzo..
Gerard
John Bokma
25/05/05, 16:45
gerard wrote:
> John Bokma wrote:
>
>> Maar ik begreep ooit uit een discussie dat zoiets nu ook middels een
>> PEAR module in PHP te doen is?
>
> Parameter binding zit ook in mysqli onder PHP5, zag ik net.
> (mysqli_stmt_bind_param o.a.)
> eveneens het escapen van karaters (mysqli_real_escape_string)
^^^^
Heerlijk dat PHP (not), het is wachten op
mysql_tng_magic_escape_really_real_string
> tis natuurlijk wel in de driver dan,
ik zie daar hier geen probleem mee (SQL injecties voorkomen)
--
John Voorbeeldscripts in Perl: http://johnbokma.com/perl/
Website design: http://johnbokma.com/websitedesign/
Ervaren Perl / Java programmeur beschikbaar: http://castleamber.com/
Tevreden opdrachtgevers: http://castleamber.com/testimonials.html
Daniel Tryba
25/05/05, 17:25
John Bokma <john@castleamber.com> wrote:
>> eveneens het escapen van karaters (mysqli_real_escape_string)
> ^^^^
>
> Heerlijk dat PHP (not), het is wachten op
> mysql_tng_magic_escape_really_real_string
Dat is nu eenmaal de naam in de mysql API
(http://dev.mysql.com/doc/mysql/en/c-api-functions.html)
John Bokma
25/05/05, 17:35
Daniel Tryba wrote:
> John Bokma <john@castleamber.com> wrote:
>>> eveneens het escapen van karaters (mysqli_real_escape_string)
>> ^^^^
>>
>> Heerlijk dat PHP (not), het is wachten op
>> mysql_tng_magic_escape_really_real_string
>
> Dat is nu eenmaal de naam in de mysql API
Ah, ik vroeg mij al af waarom het niet real_mysqli_string_escape was :-)
--
John Voorbeeldscripts in Perl: http://johnbokma.com/perl/
Website design: http://johnbokma.com/websitedesign/
Ervaren Perl / Java programmeur beschikbaar: http://castleamber.com/
Tevreden opdrachtgevers: http://castleamber.com/testimonials.html