[PHP/MySQL] SQL injectie voorkomen

Pagina: 1 2 3 4 Laatste
Acties:
  • 18.115 views

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
pedorus schreef op donderdag 02 oktober 2008 @ 14:29:
Mensen die zo'n functie gebruiken zullen de variabelen meestal toch niet bewerken, dus over het algemeen is het korter. :)
"$a = f(); g($a);" is toch langer dan "g(f());"?
Omdat in meer professionele omgevingen vaak wel prepared statements gebruikt worden. Cheapo-hoster-XXX daarentegen heeft de db-server en de webserver van een site vaak op dezelfde host draaien.
Hmm, er zijn genoeg grote sites die de database- en webservers niet op dezelfde host hebben draaien maar geen prepared statements gebruiken.
Omdat je anders veel vaker een cast moet doen, wat daardoor meer typwerk is.
Ah, de var was eigenlijk om te beginnen al niet van het goede type?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23-06 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Olaf van der Spek schreef op donderdag 02 oktober 2008 @ 14:35:
[...]

"$a = f(); g($a);" is toch langer dan "g(f());"?
Ach, f()[0] werkt ook niet in PHP als f() een array teruggeeft ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
.oisyn schreef op donderdag 02 oktober 2008 @ 14:37:
Ach, f()\[0] werkt ook niet in PHP als f() een array teruggeeft ;)
Nee, helaas. :(

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23-06 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Overigens snap ik sowieso niet waarom het type überhaupt belangrijk is. Je kunt de waarden toch gewoon altijd tussen quotes in de query zetten (behalve bij null, maar daar test je dan ook op)? Waarom moet het per se conform zijn met de datatypes in je tabel?

[ Voor 14% gewijzigd door .oisyn op 02-10-2008 14:53 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Anoniem: 156876

Olaf van der Spek schreef op donderdag 02 oktober 2008 @ 14:35:
[...]

Hmm, er zijn genoeg grote sites die de database- en webservers niet op dezelfde host hebben draaien maar geen prepared statements gebruiken.
So what? :X Wat doet het er toe of grote site's er gebruik van maken of niet? Ik vraag me langzamerhand af wat jou bedoeling is met dit topic, alle échte oplossingen zijn niet goed. Er zijn 2 mooie voorbeelden gegeven van een crappy mysql_query_safe(). Veel plezier ermee! Als je echt voor veiligheid wilt gaan gebruik je zoiets als 't voorbeeld wat op PHP.net staat of prepared statements. :+

Sorry hoor, maar als je een discussie aan wilt gaan, zorg dan dat je je huiswerk maakt, en sta open voor meningen/antwoorden van mede-forummers (met meer verstand van zaken / ervaring), wat heeft deze hele discussie anders voor'n zin? 8)7

Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
.oisyn schreef op donderdag 02 oktober 2008 @ 14:52:
Overigens snap ik sowieso niet waarom het type überhaupt belangrijk is. Je kunt de waarden toch gewoon altijd tussen quotes in de query zetten (behalve bij null, maar daar test je dan ook op)? Waarom moet het per se conform zijn met de datatypes in je tabel?
Is het ook niet echt.

Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 27-05 16:00

curry684

left part of the evil twins

.oisyn schreef op donderdag 02 oktober 2008 @ 14:52:
Overigens snap ik sowieso niet waarom het type überhaupt belangrijk is. Je kunt de waarden toch gewoon altijd tussen quotes in de query zetten (behalve bij null, maar daar test je dan ook op)? Waarom moet het per se conform zijn met de datatypes in je tabel?
Omdat MySQL de enige brakke database is die integers tussen quotes pikt - SQL Server en consorten geven er harde errors op. Als je dan een abstractielaag schrijft, schrijf dat ook een portable. Voor je het weet komt de volgende MySQL-versie met een 'gedraag je als een volwassen DBMS' optie aka strict mode en valt je code om.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Olaf van der Spek schreef op donderdag 02 oktober 2008 @ 14:35:
"$a = f(); g($a);" is toch langer dan "g(f());"?
Nou, in het veelvoorkomende geval van $_GET['a'] worden er nu maarliefst 5 karakters gewonnen. Daar komt de winst vandaan. Niet van dit minder vaak voorkomende geval natuurlijk..

En dan heb ik het nog niet eens over versie 2.0. In deze versie wordt de ${} operator ingevoerd, waarbij alles tussen { en } wordt uitgevoerd als php-functie (met wellicht wat beperkingen). Daarmee is het verschil bij functies teruggelopen tot 0 karakters! :)
Komt ie }) :
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function mysql_query_safe($query) {
    function escaped($matches) {
        if ($matches[3]) return '$';
        if ($matches[4]) {
            extract($GLOBALS);
            $s=eval('return '.$matches[4].';');
        } else
            $s=$GLOBALS[$matches[1]];
        if ($matches[2]) $s=$s[$matches[2]];
        return '"'.mysql_real_escape_string($s).'"';
    }
    $query=preg_replace_callback(
      '/\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(?:\[(.*?)])?|(\$\$)|\$\{(.*?)}/',
      'escaped',$query,-1,$count);
    if ($count>0) return mysql_query($query);
    throw new Exception('No parameters found in querystring');
}

$a=99;
mysql_query_safe('insert into T (A,B,C) values ($a, ${trim($_GET["b"])}, $_GET[c])');
Ah, de var was eigenlijk om te beginnen al niet van het goede type?
Misschien kunnen we beter alle browsers ook veranderen? Daar komt zo'n string meestal vandaan...
.oisyn schreef op donderdag 02 oktober 2008 @ 14:52:
Overigens snap ik sowieso niet waarom het type überhaupt belangrijk is. Je kunt de waarden toch gewoon altijd tussen quotes in de query zetten (behalve bij null, maar daar test je dan ook op)? Waarom moet het per se conform zijn met de datatypes in je tabel?
Afgezien van wat kleine details bij doubles ('18015376320243459' <> 18015376320243459), is er niet echt verschil bij MySQL inderdaad. Ik heb het aangepast :)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • chris
  • Registratie: September 2001
  • Laatst online: 11-03-2022
Anoniem: 156876 schreef op donderdag 02 oktober 2008 @ 09:27:
[...]

Het is niet per definitie onveilig om mysql_query te gebruiken. Als er correct gebruik gemaakt van wordt is het net zo veilig als bijv. PDO. Het verwijderen van die functie zal dan ook nooit gaan gebeuren.

Als de tutorials het niet veilig uitleggen, is het dan de fout van PHP? Het moet toch niet veel gekker worden... :P
Het zou ook geen probleem zijn om een lower-level functie beschikbaar te hebben. Noem 'm dan bijvoorbeeld unsafe_mysql_string om expliciet aan te geven dat 't nog niet gequote is. Het enige wat ik bedoel is dat de default meteen veilig moet zijn.

Als je niet weet waar je mee bezig bent en toch onveilige code produceert dan heb je een probleem. Natuurlijk is het beste om te zeggen dat mensen maar meer moeten lezen/leren, maar er is ook een alternatief: stel nou dat PHP een warning geeft als je zomaar unsafe_mysql_query gebruikt. Of nog beter: dat PHP kan checken of je gebruik wel of niet veilig is. Bijvoorbeeld: integers zijn altijd veilig, strings die zijn geescaped ook, maar al het andere is onveilig. Ach, het is een leuk idee, maar of het ooit zo ver komt....

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
chris schreef op donderdag 02 oktober 2008 @ 16:13:
Als je niet weet waar je mee bezig bent en toch onveilige code produceert dan heb je een probleem. Natuurlijk is het beste om te zeggen dat mensen maar meer moeten lezen/leren, maar er is ook een alternatief: stel nou dat PHP een warning geeft als je zomaar unsafe_mysql_query gebruikt. Of nog beter: dat PHP kan checken of je gebruik wel of niet veilig is. Bijvoorbeeld: integers zijn altijd veilig, strings die zijn geescaped ook, maar al het andere is onveilig. Ach, het is een leuk idee, maar of het ooit zo ver komt....
Het zou mooi zijn als PHP ook taint checking kan doen inderdaad.
Maar het zou nog mooier zijn als iedereen gewoon prepared statements zou gebruiken indien mogelijk. :)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 09-06 21:17
Ik heb een poosje geprobeerd queries samen te stellen met sprintf maar zeker bij queries met meerdere kolommen vond ik het erg onoverzichtelijk worden.
Momenteel zweer ik bij de volgende functie waar ik gewoon een assosiatieve array in kan kwakken; key's zijn de kolomnamen en value's de bijbehorende waarden. Null's en false's worden als null opgeslagen, en strings escaped. Enige probleem is dat ik geen functions zoals NOW() kwijt kan;
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function arrayToInsertSQL($arr, $link_identifier = false) {
    $columns = $values = array();
    
    foreach($arr as $column => $value) {
        $columns[] = $column;
        if(is_null($value) || $value === false) {
            $values[] = "NULL";
        } elseif(is_numeric($value) && $value{0} != '0') {
            $values[] = $value;
        } else {
            if(ini_get('magic_quotes_gpc')) {
                $values[] = "'" . $value . "'";
            } elseif($link_identifier) {
                $values[] = "'" . mysql_real_escape_string($value, $link_identifier) . "'";
            } else {
                $values[] = "'" . mysql_real_escape_string($value) . "'";
            }
        }
    }
    return "(" . implode(", ", $columns) . ") VALUES(" . implode(", ", $values) . ")";
}

$sqlValues = array();
$sqlValues['foo'] = 'bar';
$sql = 'INSERT NITO table ' . arrayToInsertSQL($sqlValues);

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23-06 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

curry684 schreef op donderdag 02 oktober 2008 @ 15:52:
Voor je het weet komt de volgende MySQL-versie met een 'gedraag je als een volwassen DBMS' optie aka strict mode
Wheehehehehe that's rich _o- :')
Anyway, point taken over dat een fatsoenlijke DB het niet pikt, dat wist ik niet :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
mysql heeft overigens al een aantal configs voor stricter gedrag, je kan zelfs de random group by data featurebug uit zetten. Probleem is alleen dat geen hond het doet. :/

@Fricky's poging: Gefeliciteerd deze functie is de meest onveilige variant in dit topic tot nu toe. :>

Magic quotes gpc is niet even goed als mysql_real_escape_string(). En in deze context weet je niet eens of $value door magic quotes gehaald is. :z Functies als deze is waarom ik maar wat blij ben als magic quotes dood is (PHP 6 ftw \o/ )

[ Voor 22% gewijzigd door Voutloos op 02-10-2008 16:46 ]

{signature}


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 27-05 16:00

curry684

left part of the evil twins

Voutloos schreef op donderdag 02 oktober 2008 @ 16:44:
Magic quotes gpc is niet even goed als mysql_real_escape_string(). En in deze context weet je niet eens of $value door magic quotes gehaald is. :z
Ik zat ook al even stom te kijken waarom ie op een input filter checkt bij het construeren van DB-queries 8)7

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Eeuwig zonde, ik had frickY redelijk hoog zitten, en dat trapt ie volle bak in een php magic k*tfeature. :'(

;)

{signature}


Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
function sql_array ( $queryType, $queryData )
{
  if ( ! is_array ( $queryData ) )
  {
      return false;
  }

  $tableFields = array ();
  $tableValues = array ();
  
  switch ( $queryType )
  {
    case 'INSERT' :
          foreach ( $queryData as $arrayKey => $arrayValue )
          {
              $tableFields[] = $arrayKey;
    
              if ( is_null ( $arrayValue ) )
              {
                  $tableValues[] = 'NULL';
              }          
              elseif ( is_string ( $arrayValue ) )
              {
                  $tableValues[] = '"' . mysql_real_escape_string ( $arrayValue ) . '"';
              }
              else
              {
                  $tableValues[] = ( is_bool ( $arrayValue ) ) ? intval ( $arrayValue ) : $arrayValue;
              }
          }
    
          $queryString = ' (' . implode ( ', ', $tableFields ) . ') VALUES (' . implode ( ', ', $tableValues ) . ')';   
    break;
    case 'UPDATE' :
          foreach ( $queryData as $arrayKey => $arrayValue )
          {
              if ( is_null ( $arrayValue ) )
              {
                  $tableValues[] = $arrayKey . ' = NULL';
              }            
              elseif ( is_string ( $arrayValue ) )
              {
                  $tableValues[] = $arrayKey . ' = "' . mysql_real_escape_string ( $arrayValue ) . '"';
              }
              else
              {
                  $tableValues[] = ( is_bool ( $arrayValue ) ) ? $arrayKey . ' = ' . intval ( $arrayValue ) : $arrayKey . ' = ' . $arrayValue;
              }
          }
          
          $queryString = ' SET ' . implode ( ', ', $tableValues );  
    break;
  }
  
  return $queryString;
}

$sqlValues = array ();
$sqlValues['naam'] = 'Karel';
$sqlValues['leeftijd'] = 21;
printf ( 'INSERT INTO table %s', sql_array ( 'INSERT', $sqlValues ) );

March of the Eagles


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
En ook deze functie is niet veilig. :X
Voutloos schreef op dinsdag 30 september 2008 @ 21:11:Of nog wat duidelijker: met mysql_real_escape_string() op iets dat geen string is (dwz niet binnen quotes staat in de query) helpt dus onvoldoende tegen injection. Hmz, misschien is die functie wel bedoeld voor het echt :+ escapen van strings in een mysql context.
Mensen, geef het aub toch op....

{signature}


Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
Dan zetten we er quotes om.

Weet niet of iemand ervaring met PDO heeft?

PHP:
1
2
3
4
5
6
7
8
9
10
$database = new PDO ( sprintf ( 'mysql:host=%s;dbname=%s', $hostName, $dbName ), 'username', 'password' );

$sqlData = array ();
$sqlData[':name'] = 'Karel';
$sqlData[':age'] = 21;

$object = $database->prepare ( 'SELECT * FROM users WHERE name = :name AND age = :age;' );
$object->execute ( $sqlData );

var_dump ( $object->fetchAll ( PDO::FETCH_ASSOC ) );

[ Voor 89% gewijzigd door XWB op 02-10-2008 17:27 ]

March of the Eagles


Acties:
  • 0 Henk 'm!

  • vorlox
  • Registratie: Juni 2001
  • Laatst online: 02-02-2022

vorlox

I cna ytpe 300 wrods pre miute

Prepared staments is beter. PDO is makkelijk om het mee te doen.
Toch vond ik voor het snelle scriptwerk die van Fricky en Hacku best aardig
Effe die 2 goed bekeken kom ik bij zoiets
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
function mysql_safe_insert($table,$values=array(),$fromGpc=false,$link_identifier=NULL)
{
    //Var
    $insertKeys = array();
    $insertValues = array();
    
    //Loop values
    foreach($values as $key=>$value)
    {
        //Add key
        $insertKeys[] = "`".$key."`";
        
        //Test value
        if(is_null($value))
            $insertValues[] = 'NULL';
        elseif(is_numeric($value))
            $insertValues[] = $value;
        elseif(is_string($value))
        {
            //Test if we need GPC escape
            if( $fromGpc && get_magic_quotes_gpc())
                $value = stripslashes($value);
            //Test link
            if(is_null($link_identifier))
                $insertValues[] = "'".mysql_real_escape_string($value)."'";
            else
                $insertValues[] = "'".mysql_real_escape_string($value,$link_identifier)."'";
        }
    }
    
    //Build insert query
    $query = "INSERT INTO `".$table."` (".implode(', ',$insertKeys).") VALUES (".implode(', ',$insertValues).") ";
    
    return mysql_query($query);
}
//Usage
$data = array();
$data['ham'] = '121';
$data['kaas'] = "'; DROP DATABASE;";
$data['dropje'] = NULL;
mysql_safe_insert('mytable',$data,false,$link);

[ Voor 6% gewijzigd door vorlox op 02-10-2008 18:15 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23-06 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nogmaals, waarom kijk je in hemelsnaam naar de magic_quotes_gpc setting? Als die nou aanstaat gaat je ' in $data["kaas"] niet geescaped worden, omdat je de aanname maakt dat ie al geescaped is. Maar hij komt helemaal niet uit de Get, Post of Cookie!!!

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • vorlox
  • Registratie: Juni 2001
  • Laatst online: 02-02-2022

vorlox

I cna ytpe 300 wrods pre miute

Uhh daarom heb ik toch die boolean om aan te geven of het uit een POST of GET komt?
Dus de aanname geef je zelf mee. In het voorbeeld geef ik false. omdat het dus niet uit een GET of POST komt.
Overigens wordt uiteindelijk toch alles ge-escaped, maar misschien zie ik iets niet...zo niet gebruik dan prepared statements.
PHP:
1
2
//Usage 
mysql_safe_insert('mytable',$_POST,true,$link);

Dan lijkt het toch te kloppen.

[ Voor 75% gewijzigd door vorlox op 02-10-2008 18:06 ]


Acties:
  • 0 Henk 'm!

Anoniem: 156876

:'( :'( :'( :'( :'( :'( :'( :'( :'(

Gebruik nou gewoon functie's die er voor gemaakt zijn!!! En,... je escaped je keys niet...? :X

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
vorlox schreef op donderdag 02 oktober 2008 @ 17:50:
Prepared staments is beter. PDO is makkelijk om het mee te doen.
Toch vond ik voor het snelle scriptwerk die van Fricky en Hacku best aardig
Effe die 2 goed bekeken kom ik bij zoiets
Dat stukje over magic_quotes hoort daar echt niet, ook niet met boolean... Wat als je zowel eigen/bewerkte als postdata hebt?

Ik zou dan toch nog liever mijn eigen mysql_query_safe (v2.1 met extra regeltje voor is_null) gebruiken. Dan hoef je geen nieuwe commando's te leren, maar kun je gewoon sql gebruiken. En je kan bijvoorbeeld ook nog "0123" inserten als string zonder dat het mis gaat...

En mysql_query_safe is volgens de auteur een slechter idee dan prepared statements... Hou het dus maar bij prepared statements :)
vorlox schreef op donderdag 02 oktober 2008 @ 18:01:
PHP:
1
2
//Usage 
mysql_safe_insert('mytable',$_POST,true,$link);
Het voordeel van mysql_query_safe is ook dat dit soort ongein niet mogelijk is :) (zie post hierboven)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • WernerL
  • Registratie: December 2006
  • Laatst online: 18:05
Ik gebruik tegenwoordig, net zoals een persoon hier heel wat posts boven deze, PDO. In tegenstelling met mysqli kun je parameters een naam geven waardoor je queries wat overzichtelijker zijn.

PHP:
1
2
$sql = $db->prepare("SELECT * FROM blaat WHERE iets = :woei");
$sql->bindParam(":woei", $_POST['hoi'], PDO::PARAM_STR);


zo wordt ook gelijk alles ge-escaped zonder dat je een lange onoverzichtelijke querie krijgt.
In mysqli werkt dat met vraagtekens... :( Vind ik toch weer jammer.

Roses are red, violets are blue, unexpected '{' on line 32.


Acties:
  • 0 Henk 'm!

Anoniem: 156876

Groot gedeelte van de mooie functies kunnen beter rechtstreeks geplaatst worden in [alg] Slechtste programmeervoorbeelden deel 4... :/ Gebruik de functies zoals ze bedoeld zijn dan is het veilig! |:(

Dus prepared statements / correcte manier via mysql_query(). :D

Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
pedorus schreef op donderdag 02 oktober 2008 @ 18:50:
[...]

Dat stukje over magic_quotes hoort daar echt niet, ook niet met boolean... Wat als je zowel eigen/bewerkte als postdata hebt?
Is het geen idee om stripslashes toe te passen, wanneer magic_quotes aanstaat? Even quick uit de losse hand:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function stripSlashes ()
{
    set_magic_quotes_runtime ( 0 );
    
    if ( get_magic_quotes_gpc () )
    {
        $_SERVER = stripslashes_array ( $_SERVER );
        $_GET = stripslashes_array ( $_GET );
        $_POST = stripslashes_array ( $_POST );
        $_COOKIE = stripslashes_array ( $_COOKIE );
        $_FILES = stripslashes_array ( $_FILES );
        $_ENV = stripslashes_array ( $_ENV );
        $_REQUEST = stripslashes_array ( $_REQUEST );
    }
}

function stripslashes_array ( $data )
{
    if ( is_array ( $data ) )
    {
        foreach ( $data as $key => $value )
            $data[$key] = stripslashes_array ( $value );
            
        $return = $data;
    }
    else
    {
        $return = stripslashes ( $data );
    }
    
    return $return;
}

stripSlashes ();

March of the Eagles


Acties:
  • 0 Henk 'm!

  • WernerL
  • Registratie: December 2006
  • Laatst online: 18:05
Het is toch totaal overbodig om de $_SERVER variabel te stripslashen ?
En is de $_REQUEST superglobal niet een andere manier om _GET en _POST vars op te vragen ?

Correct me if I'm wrong...

Roses are red, violets are blue, unexpected '{' on line 32.


Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
$_SERVER kan evengoed onveilig zijn, maar zal je waarschijnlijk nooit i.c.m. queries gebruiken. $_SERVER wordt vooral misbruikt voor XSS e.d.

$_REQUEST bevat idd alle waarden van GET, POST en COOKIE en wordt eigenlijk zelden gebruikt. Als je hem niet gebruikt kan je hem idd weglaten.

March of the Eagles


Acties:
  • 0 Henk 'm!

  • GC-Martijn
  • Registratie: September 2004
  • Laatst online: 09-12-2018
Ik zit toch met enige verbazing te kijken naar deze topic.

De titel is: [PHP/MySQL] SQL injectie voorkomen

dus dan denk ik (puur voor mysql gebruik only) http://nl.php.net/manual/...ql-real-escape-string.php
PHP:
1
2
3
4
// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
            mysql_real_escape_string($user),
            mysql_real_escape_string($password));


---- of wat er verderop staat beschreven

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Using mysql_real_escape_string() around each variable prevents SQL Injection. This example demonstrates the "best practice" method for querying a database, independent of the Magic Quotes setting. 

<?php

if (isset($_POST['product_name']) && isset($_POST['product_description']) && isset($_POST['user_id'])) {
    // Connect

    $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');

    if(!is_resource($link)) {

        echo "Failed to connect to the server\n";
        // ... log the error properly

    } else {
        
        // Reverse magic_quotes_gpc/magic_quotes_sybase effects on those vars if ON.

        if(get_magic_quotes_gpc()) {
            $product_name        = stripslashes($_POST['product_name']);
            $product_description = stripslashes($_POST['product_description']);
        } else {
            $product_name        = $_POST['product_name'];
            $product_description = $_POST['product_description'];
        }

        // Make a safe query
        $query = sprintf("INSERT INTO products (`name`, `description`, `user_id`) VALUES ('%s', '%s', %d)",
                    mysql_real_escape_string($product_name, $link),
                    mysql_real_escape_string($product_description, $link),
                    $_POST['user_id']);

        mysql_query($query, $link);

        if (mysql_affected_rows($link) > 0) {
            echo "Product inserted\n";
        }
    }
} else {
    echo "Fill the form properly\n";
}
?> 


The query will now execute correctly, and SQL Injection attacks will not work.

Ik persoonlijk dacht echt dat dit 'voldoende' was om een SQL injection te voorkomen.
Als dit niet zo is dan hoor ik dat zeer graag.

[ Voor 0% gewijzigd door een moderator op 21-10-2008 22:10 . Reden: Code tags toegevoegd... ]

// - bla la


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 09-06 21:17
@Voutloos, curry684
Val ik even door de mand :p
Laat ik me allereerst verdedigen dat deze er van origine niet in zat, maar ik de functie ooit op een server van een externe partij heb gebruikt waar magiq_quotes - ook tot mijn spijt - aanstond en daar ook veelvuldig gebruik van werd gemaakt. Mijn functie escapte daardoor de escapes die magiq_quotes al had gemaakt in de ontvangen POST-data. Dit was daar een eenvoudige work-around op.

Maar voor waarom dit de meest slechte variant zou zijn hoor ik graag een verklaring, want ik zie het niet :s De functie is uitermate overzichtelijk in gebruik en, voor voorkomt, voor zover ik dus weet, injection :)

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Hacku schreef op donderdag 02 oktober 2008 @ 21:32:
Is het geen idee om stripslashes toe te passen, wanneer magic_quotes aanstaat? Even quick uit de losse hand:
Het idee is goed, maar ik zou toch even hier naar kijken om die DOS-attack tegen te gaan. Daarnaast heeft magic quotes alleen effect op GPC-data, en niet op bijvoorbeeld server..
frickY schreef op donderdag 02 oktober 2008 @ 21:56:
Laat ik me allereerst verdedigen
Verdedigen is natuurlijk zinloos na zo door de mand gevallen te zijn ;)
Maar voor waarom dit de meest slechte variant zou zijn hoor ik graag een verklaring, want ik zie het niet :s De functie is uitermate overzichtelijk in gebruik en, voor voorkomt, voor zover ik dus weet, injection :)
Hangt van je karakterset af. Magic quotes doet addslashes. Zie hier:
Despite the use of addslashes(), I'm able to log in successfully without knowing a valid username or password. I can simply exploit the SQL injection vulnerability.

[ Voor 46% gewijzigd door pedorus op 02-10-2008 22:22 ]

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
GC-Martijn schreef op donderdag 02 oktober 2008 @ 21:49:
Using mysql_real_escape_string() around each variable prevents SQL Injection. This example demonstrates the "best practice" method for querying a database, independent of the Magic Quotes setting.
Dit klopt in principe wel, alleen alles als string representeren leidt weer tot andere problemen als je query's op wilt bouwen adhv variabelen etc.
Voor simpele get / post variabelen werkt het afaik best, alleen soms heb je ook een verschil tussen '1' en 1 ( de int-waarde dus ). Als jij een query programmatechnisch gaat samenstellen doe jij imho echt niet een simpele mysql_real_escape_string, hier ga je zwaar mee in de knoei komen met grotere query's met vele variabelen.
Als je het toch doet zeg dan maar dag tegen je indexen etc.
Ik persoonlijk dacht echt dat dit 'voldoende' was om een SQL injection te voorkomen.
Als dit niet zo is dan hoor ik dat zeer graag.
Het is afaik voldoende om sql-injections te voorkomen, alleen afaik is het ook killing voor je dbase om alles op deze manier te doen. Voor een simpele query maakt het niet zoveel uit, maar als je meerdere joins / grotere query's gaat maken wil je toch echt wel 100% gebruik maken van alle indexen en dan gaat het steken...

Acties:
  • 0 Henk 'm!

  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Is het niet mogelijk om een mysql_query_safe() functie te schrijven, die gebruik maakt van prepared statements? Dan is iedereen in dit topic volgens mij blij O-)

TabCinema : NiftySplit


Acties:
  • 0 Henk 'm!

  • link0007
  • Registratie: Augustus 2006
  • Laatst online: 24-06 22:48
Bozozo schreef op donderdag 02 oktober 2008 @ 22:28:
Is het niet mogelijk om een mysql_query_safe() functie te schrijven, die gebruik maakt van prepared statements? Dan is iedereen in dit topic volgens mij blij O-)
err, dus dat komt neer op iets als dit:

PHP:
1
2
3
4
function specialEchoFunctionExtremeAwesome($foo)
{
   echo $foo;
}


:S

Gebruik gewoon meteen prepared statements.

IF IF = THEN THEN THEN = ELSE ELSE ELSE = IF;


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 09-06 21:17
pedorus schreef op donderdag 02 oktober 2008 @ 21:58:
Hangt van je karakterset af. Magic quotes doet addslashes. Zie hier:
Je punt is dat mijn functie unsafe is wanneer maqic_quotes aanstaat. Daar heb je gelijk is. Maar het is in principe ook niet mijn bedoeling op servers te werken waar dat het geval is :p

Magic_quotes_gpc escaped overigens inderdaad alleen GET, POST en COOKIE (hence the name) data. Zijn broertje magiq_quotes_runtime escaped echter ook data die je bijvoorbeeld uit files leest ( |:( ). Maar dat terzijde.

Acties:
  • 0 Henk 'm!

  • Patriot
  • Registratie: December 2004
  • Laatst online: 14:14

Patriot

Fulltime #whatpulsert

frickY schreef op vrijdag 03 oktober 2008 @ 00:31:
[...]

Je punt is dat mijn functie unsafe is wanneer maqic_quotes aanstaat. Daar heb je gelijk is. Maar het is in principe ook niet mijn bedoeling op servers te werken waar dat het geval is :p
Nee, zijn punt is dat wanneer je addslashes gebruikt, het toch mogelijk is om quotes in je query te krijgen (en je dus kunt injecten).

Acties:
  • 0 Henk 'm!

  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 23-06 20:44
frickY schreef op vrijdag 03 oktober 2008 @ 00:31:
[...]

Je punt is dat mijn functie unsafe is wanneer maqic_quotes aanstaat. Daar heb je gelijk is. Maar het is in principe ook niet mijn bedoeling op servers te werken waar dat het geval is :p

Magic_quotes_gpc escaped overigens inderdaad alleen GET, POST en COOKIE (hence the name) data. Zijn broertje magiq_quotes_runtime escaped echter ook data die je bijvoorbeeld uit files leest ( |:( ). Maar dat terzijde.
Maar wat je dan zou kunnen doen is checken of die magic_quotes_gpc ellende aanstaat, en als dat zo is stripslashes eroverheen gooien (omgekeerde van addslashes) en het dan alsnog in mysql_real_escape_string donderen, toch?

Probleem blijft dan inderdaad wel of het GPC data is of niet....

Edit: ah dat is wat Vorlox dus doet... nvm beetje te laat en te lui om code door te lezen :+

[ Voor 5% gewijzigd door Morrar op 03-10-2008 01:11 ]


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Hacku schreef op donderdag 02 oktober 2008 @ 21:32:
[...]
Is het geen idee om stripslashes toe te passen, wanneer magic_quotes aanstaat? Even quick uit de losse hand:
Dit doen op de relevante superglobals helemaal aan het begin van je script is een goed idee. Dan heb je na dat punt helemaal niets meer met magic quotes gpc van doen, en op het moment dat het eruit gaat (PHP 6) hoef je enkel de 1e 5 regels van je script te dumpen. Strip de slashes dan wel volgens de link van pedorus, want jouw implementatie heeft dus een probleem. ;)

Maar wat doe je dan tegen magic quotes runtime? Simpel: uitzetten aan begin van je script en verder helemaal niets. Gaat het niet uit, of zet een library het weer aan? Jammer dan, mysql_real_escape_string blijft nodig, dus dan maar kans op dubbele escaping. Bij klachten zeg je dat de config niet ondersteund wordt.

O enne, stripSlashes() is stomme functienaam. Case sensitivity heerscht (naamgeving in PHP wat minder :+ ), maar zoek dan niet express 'dubbele' functienamen op.
frickY schreef op donderdag 02 oktober 2008 @ 21:56:
Dit was daar een eenvoudige work-around op.
De verkeerde work around dus. ;)
Maar voor waarom dit de meest slechte variant zou zijn hoor ik graag een verklaring, want ik zie het niet :s De functie is uitermate overzichtelijk in gebruik en, voor voorkomt, voor zover ik dus weet, injection :)
Als je in magie trapt is het per definitie de slechtste. :+ Bij het doen van je work around heb je dus onvoldoende uitgezocht of magic quotes voldoende is en daarmee een slordigheid (dubbele escaping) gepromoveerd tot een security leak.

[ Voor 9% gewijzigd door Voutloos op 03-10-2008 08:25 ]

{signature}


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 27-05 16:00

curry684

left part of the evil twins

De handigste manier om het hele GPC-verhaal kort te sluiten is simpelweg - ze niet binnen laten komen. Gewoon een eigen request class bouwen die de externe inputs encapsuleert, en daarbinnen intern mag je de magic quotes settings allemaal controleren (dus ook _sybase!) en die ongedaan maken... waarna je alle superglobals trasht en alle data vervolgens, waar ie ook vandaan komt, per definitie inject-onveilig is. Scheelt je zo maar honderden per-ongeluk-gevalletjes van redundant slashes in output files, dubbel geescapete data in je DB en andersom sql injection gaten.

Helaas moet je voor deze oplossing wel kunnen programmeren, want ineens moet je nadenken voor je een regel code schrijft die iets met data doet. Oh wacht, da's de hele essentie van programmeren.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 09-06 21:17
Maar ik snap nu wat je bedoeld. In plaats van de $value maar gewoon te vertrouwen wanneer magic_quotes_gpc aanstaat had ik de value beter kunnen stripslashen en alsnog door mysql_real_escape_string kunnen trekken. Lang niet alle values komen uit GPC, maar het was allicht 'securder' geweest dan de huidige implementatie.

Op diezelfde server riep ik bovenin overigens ook het volgende aan
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function undoMagicquotes() {
    if (!ini_get('magic_quotes_gpc')) {
        return false;
    } else {
        foreach ($_GET as $var => $val) {
            $_GET[$var] = stripslashes($val);
        }
        foreach ($_POST as $var => $val) {
            $_POST[$var] = stripslashes($val);
        }
        foreach ($_COOKIE as $var => $val) {
            $_COOKIE[$var] = stripslashes($val);
        }
        ini_set('magic_quotes_gpc', false);
        return true;
    }
}

Dus als het goed is, is alles alsnog nog mysql_real_escape_string() geweest :p
Vraag me nu alleen af of het nodig is de numerieke waarde, die niet met 0 begint, ook nog door floatval() te trekken, of dat dat overbodig is als is_numeric al aangeeft dat de waarde numeriek is.

Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
Hm, en wat als er nou een array uit GET of POST komt? Ik bedoel dus dit:

PHP:
1
2
$_GET['person']['name'] = 'Karel';
$_GET['person']['age'] = 21;


Zie dan ook mijn oplossing Hacku in "\[PHP/MySQL] SQL injectie voorkomen"

March of the Eagles


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23-06 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dat een waarde door is_numeric als numeriek wordt bestempeld wil niet zeggen dat die waarde semantisch gezien een numeriek type moet zijn. Als ik besluit ergens een username "1337" aan te maken is dat niet ineens een nummer - het blijft een string. Nou gaat het daar niet eens zozeer fout, maar wat als mijn naam nou "1337aap" was geweest? Jouw floatval maakt er dan gewoon een 1337 van. Dat was mijn username niet.

.edit @ hacku: ah ja, die oplossing die veel te veel deed omdat magic_quotes_gpc alleen van invloed is op get, post en cookie vars. Maar idd, je moet het wel recursief doen ;)

[ Voor 42% gewijzigd door .oisyn op 03-10-2008 12:05 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
Het ging om het idee, die andere superglobals laat je maar weg.

March of the Eagles


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
frickY schreef op vrijdag 03 oktober 2008 @ 11:54:
... ini_set('magic_quotes_gpc', false)...

Dus als het goed is, is alles alsnog nog mysql_real_escape_string() geweest :p
Holy shit dude, je maakt het alleen maar erger. :X |:(

Het gaat om gpc, en daar vat runtime niets aan te setten. Oftewel, magic_quotes_gpc blijft aan en je hebt gewoon alles gestript en je doet gewoon nooit mysql_real_escape_string(). Als ik jou was, zou ik dit nog even dubbelchecken om vervolgens al je klanten een hotfix te mogen geven. :X

Is was het nog wat gechargeerd, maar bij deze is jw code definitely de onveilige. :> Na meerdere hints heb je gewoon nog steeds niet de documentatie erbij gepakt...

En amen @ curry.
.oisyn schreef op vrijdag 03 oktober 2008 @ 12:02:
.edit @ hacku: ah ja, die oplossing die veel te veel deed omdat magic_quotes_gpc alleen van invloed is op get, post en cookie vars. Maar idd, je moet het wel recursief doen ;)
Ja, maar niet zo. :Y) Zie eerder gegeven link in post van Pedorus.

[ Voor 37% gewijzigd door Voutloos op 03-10-2008 13:54 ]

{signature}


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
frickY schreef op vrijdag 03 oktober 2008 @ 11:54:
Dus als het goed is, is alles alsnog nog mysql_real_escape_string() geweest :p
Nee, alles gaat nu keurig zonder slashes naar de database, want ini_set doet niks en je hebt net stripslashes gedaan (zie ook hierboven)... Ik raad aan om een testcase met "a'\"a\\" op te nemen...
Vraag me nu alleen af of het nodig is de numerieke waarde, die niet met 0 begint, ook nog door floatval() te trekken, of dat dat overbodig is als is_numeric al aangeeft dat de waarde numeriek is.
En neem dan ook "01010","1010","101E1" en "+1010" als namen op. Die moeten allen uniek zijn (en dat gaat nu niet goed).

Volgens mij zit er gewoon een probleem als mensen 'handige' 'standaard' 'veilige' functies gaan schrijven... Gaat altijd net mis :) (Behalve mysql_query_safe natuurlijk :+) Daarnaast moet iemand die onbekend is met de code het dan vervolgens eerst proberen te begrijpen. Gooi die code gewoon weg en gebruik gewoon prepared statements!
Hacku schreef op vrijdag 03 oktober 2008 @ 12:06:
Het ging om het idee, die andere superglobals laat je maar weg.
Heb je deze info nu al daarop getest?
this will consume all of the servers memory and crash the script.
PHP:
1
2
$qry = str_repeat('[]', 1024);
file_get_contents('http://example.com/site.php?a' . $qry . '=1');

Use the following faster and safer script.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
if (get_magic_quotes_gpc()) {
        $in = array(&$_GET, &$_POST, &$_COOKIE);
        while (list($k,$v) = each($in)) {
                foreach ($v as $key => $val) {
                        if (!is_array($val)) {
                                $in[$k][$key] = stripslashes($val);
                                continue;
                        }
                        $in[] =& $in[$k][$key];
                }
        }
        unset($in);
}

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 27-05 16:00

curry684

left part of the evil twins

Overigens hebben prepared statements (of parametrized queries) nog een heel groot voordeel wat hier nog nergens wordt genoemd - doordat bij de betere DBMS'en deze zelf mag uitzoeken hoe hij de 'base query' combineert met de parametrisering is het mogelijk om execution plans en compiled queries beter te cachen, terwijl bij 'on the fly' de database soms niet kan zien dat het essentieel dezelfde query is - wat je databaseserver extra belast en je totale execution times vertraagt.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Ik gebruik voor mini-projectjes altijd deze functie: (die volgens mij als voorbeeld op php.net staat ook)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
function makeDbSafeString($argStrString)
{
    // strip the slashes from the string if done with magic quotes
    if(get_magic_quotes_gpc())
    {
        $argStrString   = stripslashes($argStrString);
    }
    
    // make it safe for mysql
    $argStrString = mysql_real_escape_string($argStrString);
    
    return $argStrString;
}


Voor de normale projecten lekker PDO :)

[ Voor 5% gewijzigd door Cartman! op 03-10-2008 14:33 ]


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 27-05 16:00

curry684

left part of the evil twins

Hmmm da's pas de 10e functie die het niet toestaan dat je "\o/" uit een file leest en in je DB wil zetten.....

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Dat gebruik ik ook alleen voor input via GET/POST vars. Als je de string "\o/" wil inserten volstaat het gebruik van mysql_real_escape_string() gewoon...

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Of je leest het topic gewoon. :z Is nog leuk om te doen ook, omdat dit topic [alg] Slechtste programmeervoorbeelden deel 4 echt in alle aspecten overtreft. :X

{signature}


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23-06 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Woei
IE is not supported - please use Firefox, Safari, Konqueror or just about anything else.
Another fine piece of engineering :z

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 27-05 16:00

curry684

left part of the evil twins

.oisyn schreef op vrijdag 03 oktober 2008 @ 15:23:
[...]

Woei

[...]

Another fine piece of engineering :z
LOL, en dat op een site met 'best practices' in de URL, geen doctype en een kudde validation errors op de HTML 4.01 Transitional fallback :D

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

curry684 schreef op vrijdag 03 oktober 2008 @ 14:04:
Overigens hebben prepared statements (of parametrized queries) nog een heel groot voordeel wat hier nog nergens wordt genoemd - doordat bij de betere DBMS'en deze zelf mag uitzoeken hoe hij de 'base query' combineert met de parametrisering is het mogelijk om execution plans en compiled queries beter te cachen, terwijl bij 'on the fly' de database soms niet kan zien dat het essentieel dezelfde query is - wat je databaseserver extra belast en je totale execution times vertraagt.
Hey, nou niet zo naast je schoenen lopen he? ;) Dit puntje heb ik al aangekaart op de eerste pagina :P
prototype in "\[PHP/MySQL] SQL injectie voorkomen"

Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 27-05 16:00

curry684

left part of the evil twins

Ah sorry kon tussen de brakke lappen code het bos niet meer zien ;) :*

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
pedorus schreef op vrijdag 03 oktober 2008 @ 13:59:
[...]
Heb je deze info nu al daarop getest?

[...]
Tja, een website "best practices" waarvan de html code niet valid is, niet werkt in alle browsers en zinnige namen voor de variabelen was vast ook teveel werk.

Waarom doet hij op het einde een unset (), heeft php geen garbage collector die ongebruikte variabelen zelf opruimt?

March of the Eagles


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 16:33

MueR

Admin Tweakers Discord

is niet lief

Jawel. Daar unset is pointless

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 23-06 13:51

NMe

Quia Ego Sic Dico.

Onderaan de pagina is het pointless, eerder op de pagina niet noodzakelijkerwijs. :Y)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • DexterDee
  • Registratie: November 2004
  • Laatst online: 14:42

DexterDee

I doubt, therefore I might be

LauPro schreef op donderdag 02 oktober 2008 @ 00:27:
[...]
Zolang er geen LINQ-achtige implementaties zijn blijven geprepareerde statementen icm SQL een vorm van workaround en een onnodige layer in de applicatie.
Het is je geluksdag :P
Zie hier: http://www.codeplex.com/PHPLinq

Klik hier om mij een DM te sturen • 3245 WP op ZW


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Hacku schreef op maandag 06 oktober 2008 @ 21:35:
Tja, een website "best practices" waarvan de html code niet valid is, niet werkt in alle browsers en zinnige namen voor de variabelen was vast ook teveel werk.
Tsja, straks is php.net ook al geen goede source voor info over php meer... Ze hebben trouwens echt iets tegen IE, die site is namelijk zelfs te bekijken met lynx ;)

Je kunt het toch gewoon uittesten of je server crashed als je het niet gelooft? (En zo ja, bij hoeveel van dat soort requests dat is...) :)
Waarom doet hij op het einde een unset (), heeft php geen garbage collector die ongebruikte variabelen zelf opruimt?
Vanwege de references kan dat vervelend uitpakken als je de variabele gaat hergebruiken. En in het algemeen is het een goed idee als je niet weet wat voor code er volgt. Kijk anders eens of je dit snapt.
:)

Enkel als ik vlug kijk lijkt het wel alsof ze niet aan LINQ to SQL doen. En alles is stiekem string, het lijkt zo wel op mijn mysql_safe_query...
Van hier:
Do you remember what LINQ stands for? It stands for Language Intergrated Query. Unfortunately, PHPLinq isn’t a language integrated query
In the real world LINQ is used mostly as a SQL replace, we don’t have to write the queries in strings anymore and catch the exceptions when running an application. But unfortunately we cannot do the same with PHPLinq, it still forces us to put the queries into strings.

[ Voor 31% gewijzigd door pedorus op 06-10-2008 23:38 ]

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
Dat snap ik perfect en ben ik ook bekend mee. Eén van de fouten van php, dat $var buiten de scope beschikbaar blijft. Juist omdat ik weet dat dit probleem bestaat zal ik hier nooit last van hebben (in de tweede foreach een andere var. naam gebruiken). Verder is het ook niet logisch dat je met een referentie de waarden van de array kan aanpassen.

[ Voor 16% gewijzigd door XWB op 06-10-2008 23:39 ]

March of the Eagles


Acties:
  • 0 Henk 'm!

  • LauPro
  • Registratie: Augustus 2001
  • Laatst online: 24-06 11:15

LauPro

Prof Mierenneuke®

Dat is dus helaas geen native implementatie en ik vraag me af of er met die syntax straks bij PHP6 nog wat overeind blijft. Desalniettemin een leuke speelse denkwijze als je het mij vraagt.

Om even terug te komen op magic_quotes. Ik laat mijn applicaties gewoon keihard errorren als ze die instelling tegenkomen, je kan imo het risico niet nemen ermee.

Inkoopacties - HENK terug! - Megabit
It is a war here, so be a general!


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Hacku schreef op maandag 06 oktober 2008 @ 23:38:
Dat snap ik perfect en ben ik ook bekend mee. Eén van de fouten van php, dat $var buiten de scope beschikbaar blijft. Juist omdat ik weet dat dit probleem bestaat zal ik hier nooit last van hebben (in de tweede foreach een andere var. naam gebruiken). Verder is het ook niet logisch dat je met een referentie de waarden van de array kan aanpassen.
Die code gebruikt referenties om een te diep gaande recursie te voorkomen. Dat is het punt. De unset is pure luxe, zodat er na de opruimactie geen restje overblijft. En als je het in een functie stopt is dat al helemaal niet meer nodig...
Het punt is dus niet browser support, of ideale naamgeving, want daar scoort die site inderdaad niet bijster goed mee. ;)

{signature}


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23-06 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hacku schreef op maandag 06 oktober 2008 @ 23:38:
Verder is het ook niet logisch dat je met een referentie de waarden van de array kan aanpassen.
Wat vind je daar precies niet logisch aan?
PHP:
1
2
3
4
5
6
7
8
$a = array(1, 2, 3);
$b = &$a;
$b = array(3, 2, 1);
var_dump($a);  // array(3, 2, 1), logisch imho

$c = &$a[1];
$c = 34;
var_dump($a);  // array(3, 34, 1), ook logisch imho


Waarom de elementen van de array uit de tweede post van dat PHP bugreport ineens references worden vind ik sowieso een design-flaw, maar ik ben er ook nog niet helemaal achter wat daar nou precies aan ten grondslag ligt... Ik vraag me ook af hoe je dat kunt zien. Hij zegt "elements have changed to references", maar variabelen in PHP zijn sowieso altijd references. Ze wijzen slechts naar een unieke plek zolang je ze niet naar iets anders laat wijzen.

[ Voor 14% gewijzigd door .oisyn op 07-10-2008 11:33 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
We hadden het dus over een foreach loop.

PHP:
1
2
3
4
5
6
$a = array ( 1, 2, 3 );

foreach ( $a as & $number )
    $number = 7;
    
var_dump ( $a ); // array ( 7, 7, 7 )

[ Voor 6% gewijzigd door XWB op 07-10-2008 11:31 ]

March of the Eagles


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23-06 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Oh dat. Dat vind ik ook gewoon logisch. Als je dat niet wilt moet je er geen reference van maken. Echter, wat minder logisch is is dat het ook een reference blijft, waardoor bij een volgende foreach met dezelfde iteratie variabele zonder reference je ineens onverwachte dingen krijgt.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Hacku schreef op dinsdag 07 oktober 2008 @ 11:30:
We hadden het dus over een foreach loop.
...
Dus vind je refs in het algemeen onlogisch?

{signature}


Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Hacku schreef op dinsdag 07 oktober 2008 @ 11:30:
We hadden het dus over een foreach loop.

PHP:
1
2
3
4
5
6
$a = array ( 1, 2, 3 );

foreach ( $a as & $number )
    $number = 7;
    
var_dump ( $a ); // array ( 7, 7, 7 )
Wat had jij dan verwacht van die code?

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Ik denk dat .oisyn meer doelt op dit gedrag dan:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$a = array ( 1, 2, 3 );

foreach ( $a as & $number )
{
    $number = 7;
}

print_r ( $a ); // array ( 7, 7, 7 ) 

foreach ( $a as $number )
{
    $number = 2;
}

print_r ( $a ); // array ( 7, 7, 2 ) 

Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 15:30

Zyppora

155/50 Warlock

In principe is het helemaal niet zo onlogisch dat de reference blijft bestaan, als je erover nadenkt. Na de eerste foreach verwijst $number nog steeds naar $a[2], en in de tweede foreach zet je de waarde van $a[2] driemaal op 2. Als je het niet doorhebt, kun je er uren mee zoet zijn, dat geef ik toe, maar het is geen unexpected behaviour als je hem eenmaal doorhebt. Het zou uiteraard mooier geweest zijn als de interpreter rekening gehouden had met het feit dat de variabele voor de loop niet ge-initialiseerd was en hem daarom op de loop gescoped had.

Edit:
Weet iemand trouwens of deze 'quirk' ook in bijv. C werkt?

Edit2: @hieronder:
Het is misschien onverwacht, maar het is niet inconsistent (tot op zekere hoogte, het zou goed kunnen dat ze dit in een andere versie 'gefixed' hebben). Het is gewoon een eigenaardigheidje van de taal en levert vziw. geen unexpected behaviour op in de zin van 'dan weer resultaat A, en dan weer resultaat B'.

[ Voor 27% gewijzigd door Zyppora op 10-10-2008 10:25 . Reden: Derde array element is '2' -.- ]

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Zyppora schreef op vrijdag 10 oktober 2008 @ 10:14:
In principe is het helemaal niet zo onlogisch dat de reference blijft bestaan, als je erover nadenkt. Na de eerste foreach verwijst $number nog steeds naar $a\[3]
$a[2] ;)

Dat is niet helemaal onlogisch, maar het zal best onverwacht zijn.
Ook leuk. ;)

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
$a = array ( 1, 2, 3 );

foreach ( $a as & $number )
{
}

print_r ( $a ); // array ( 1, 2, 3 )

foreach ( $a as $number )
{
}

print_r ( $a ); // array ( 1, 2, 2 )

Eh, C is een fatsoenlijke taal. ;)
En C kent geen foreach en references.

In C++ kun je references niet naar iets anders laten verwijzen. Dat probeer je hier in PHP wel te doen, maar dat gaat hier dus ook mis.

[ Voor 103% gewijzigd door Olaf van der Spek op 10-10-2008 10:23 ]


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 15:30

Zyppora

155/50 Warlock

Maar wel loops ;)
HUH?! En ik maar denken dat dat wel zo was :?
C++ dan misschien? (ben niet bekend met de verschillen tussen C en C++, behalve dat C++ OO is kan zijn)

[ Voor 5% gewijzigd door Zyppora op 10-10-2008 10:24 ]

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Zyppora schreef op vrijdag 10 oktober 2008 @ 10:23:
C++ dan misschien? (ben niet bekend met de verschillen tussen C en C++, behalve dat C++ OO is)
In C++ kun je references niet naar iets anders laten verwijzen. Dat probeer je hier in PHP wel te doen, maar dat gaat hier dus ook mis.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23-06 11:51

Janoz

Moderator Devschuur®

!litemod

Zyppora schreef op vrijdag 10 oktober 2008 @ 10:14:
In principe is het helemaal niet zo onlogisch dat de reference blijft bestaan, als je erover nadenkt.
Als je over een bug nadenkt is hij altijd logisch (muv hardware falen wat vaak een wat meer niet deterministisch gedrag geeft), maar dat maakt het niet ineens geen bug meer.

Persoonlijk vind ik dit 1 van de grotere design flaws in php (waarbij ook vooral naar de reacties van de ontwikkelaars gekeken moet worden). Ik kan me geen nuttig gebruik van deze bug voorstellen eigenlijk.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 15:30

Zyppora

155/50 Warlock

Excuses als ik koppig overkom, maar ik zie niet in hoe men in die tweede foreach loop de reference probeert te veranderen. Die blijft gewoon intact zoals de code nu is en het resultaat valt perfect af te leiden. Overigens wordt de reference in de eerste foreach loop tweemaal aangepast, dus het kan wel. Ik krijg het idee dat men (ik noem geen namen) dit als slordige code ziet omdat het undocumented is dat dit zich voordoet, het komt niet overeen met wat het script intuitief zou moeten doen. Ik kan genoeg redenen verzinnen om dit slordige code te noemen, maar het resultaat is er daar niet een van.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Zyppora schreef op vrijdag 10 oktober 2008 @ 10:38:
Excuses als ik koppig overkom, maar ik zie niet in hoe men in die tweede foreach loop de reference probeert te veranderen.
De intentie van de programmeur in de tweede foreach is waarschijnlijk om een kopie van het array element in $number op te slaan. Maar aangezien $number een reference is, wordt die kopie opgeslagen in het doel van die reference.

Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Janoz schreef op vrijdag 10 oktober 2008 @ 10:37:
Persoonlijk vind ik dit 1 van de grotere design flaws in php (waarbij ook vooral naar de reacties van de ontwikkelaars gekeken moet worden). Ik kan me geen nuttig gebruik van deze bug voorstellen eigenlijk.
Het is toch gewoon een gevolg van de variable 'scoping' waar PHP voor gekozen heeft?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23-06 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zyppora schreef op vrijdag 10 oktober 2008 @ 10:14:
In principe is het helemaal niet zo onlogisch dat de reference blijft bestaan, als je erover nadenkt. Na de eerste foreach verwijst $number nog steeds naar $a[2], en in de tweede foreach zet je de waarde van $a[2] driemaal op 2. Als je het niet doorhebt, kun je er uren mee zoet zijn, dat geef ik toe, maar het is geen unexpected behaviour als je hem eenmaal doorhebt.
Maar that's the whole point. Het gaat er niet om of het gedrag zelf logisch is of niet. Het gaat erom hoe handig deze zogenaamde "feature" is tijdens het programmeren. Je zegt zelf al, als je er last van krijgt kun je er uren mee zoet zijn, wat nogal onhandig is. Het is ook niet symmetrisch - je kunt wel expliciet een reference definieren, maar je kunt er niet expliciet voor zorgen dat je géén reference wilt.

Praktisch gezien moet je dus elke dangling reference unsetten, en bovendien eventueel elke tijdelijke variabele die je gaat gebruiken van tevoren unsetten zodat je zeker weet dat ie niet toevallig nog naar iets anders wijst. Dat is op z'n zachtst gezegd onhandig.
Weet iemand trouwens of deze 'quirk' ook in bijv. C werkt?
PHP's references zijn heel wat anders dan references of pointers in andere talen. In feite zijn alle variabelen in PHP eigenlijk references, alleen wijzen ze in eerste instantie nog allemaal naar een uniek stukje geheugen.

In andere talen heb je een distinctie tussen references en values, waarbij je een value expliciet moet definieren en je een reference naar een value kunt laten wijzen. Bovendien is er een duidelijk verschil tussen het toekennen van een nieuwe verwijzing aan de reference zelf en een toekenning aan de value waarnaar verwezen wordt.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 15:30

Zyppora

155/50 Warlock

MAAR, hoe is dat anders dan wanneer ik bijv. dit doe:

PHP:
1
2
3
4
5
6
7
$a[0] = 3;

if (true) {
  $number = & $a[0];
}

$number = 7;


Ook hier wordt de waarde van $a[0] naar 7 veranderd, omdat de reference blijft bestaan. Dat is niet netjes, maar deze eigenaardigheid maakt de taal an sich nog niet kreupel. Je kunt er immers gewoon rekening mee houden dat dit zich voordoet en bijv. een unset() gebruiken waar nodig.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Janoz schreef op vrijdag 10 oktober 2008 @ 10:37:
Persoonlijk vind ik dit 1 van de grotere design flaws in php (waarbij ook vooral naar de reacties van de ontwikkelaars gekeken moet worden). Ik kan me geen nuttig gebruik van deze bug voorstellen eigenlijk.
Het probleem van Derick is dat hij echt een raar idee heeft over backward compatibility. Dit wijzigen voorkomt een hele hoop wtf's en breekt geen enkel net script. Knikker het eruit en zeg bij de notes voor PHP 6 dat als je op dit gedrag vertrouwde dat je dan wellicht nog een keertje naar je code wilt kijken. Rare quircks welke alleen gebruikt kunnen worden in rare scripts in stand houden != keeping it simple.
Zyppora schreef op vrijdag 10 oktober 2008 @ 11:17:
MAAR, hoe is dat anders dan wanneer ik bijv. dit doe....
Nee, dat gedrag is gewoon intuitief. :z MAAR, ;) bij de 2e foreach verwacht je gewoon een echte value en wil je niet bij eventuele eerdere loopjes stil staan. Ja, er is geen loop scope, maar dat betekent nog niet dat huidig gedrag intuitief is.

Een bug of met tegenintuitief gedrag wordt bij PHP te vaak verklaard met iets dat enkel voor de core devvers boeit 'implementatie was zo makkelijker' of met een cliché opmerking over backwards compatability terwijl het huidige gedrag dusdanig stom is dat geen enkel good practice script erop vertrouwt.

[ Voor 34% gewijzigd door Voutloos op 10-10-2008 11:29 ]

{signature}


Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 15:30

Zyppora

155/50 Warlock

.oisyn schreef op vrijdag 10 oktober 2008 @ 11:15:
[...]

Maar that's the whole point. Het gaat er niet om of het gedrag zelf logisch is of niet. Het gaat erom hoe handig deze zogenaamde "feature" is tijdens het programmeren. Je zegt zelf al, als je er last van krijgt kun je er uren mee zoet zijn, wat nogal onhandig is. Het is ook niet symmetrisch - je kunt wel expliciet een reference definieren, maar je kunt er niet expliciet voor zorgen dat je géén reference wilt.
Dat je een reference eerst moet unsetten voordat je daar een expliciete waarde aan kunt hangen is geen rocket science. De quirk zit'em dan ook in de scope. Het voorbeeld in de bugreport probeert daar voor mijn gevoel een dramatisch verhaal aan te geven, maar het blijft een simpele quirk en als je dat in je achterhoofd houdt, hoeft er echt geen issue van gemaakt te worden en is het triviaal hier op juiste wijze mee om te springen. Dat het een workaround is, ben ik met je eens.
.oisyn schreef op vrijdag 10 oktober 2008 @ 11:15:
Praktisch gezien moet je dus elke dangling reference unsetten, en bovendien eventueel elke tijdelijke variabele die je gaat gebruiken van tevoren unsetten zodat je zeker weet dat ie niet toevallig nog naar iets anders wijst. Dat is op z'n zachtst gezegd onhandig.
Alleen voor references ;) Niet-references kun je gewoon overschrijven. Maar het is inderdaad niet de beste manier om met codeblokken en diens variabelen om te springen.
.oisyn schreef op vrijdag 10 oktober 2008 @ 11:15:
[...]

PHP's references zijn heel wat anders dan references of pointers in andere talen. In feite zijn alle variabelen in PHP eigenlijk references, alleen wijzen ze in eerste instantie nog allemaal naar een uniek stukje geheugen.
Ik geef toe dat er wat dat betreft nogal wat aan PHP schort, maar da's een andere discussie vrees ik. Ik vraag me af wat functioneel gezien het verschil tussen een reference in PHP en een reference/pointer in een willekeurig andere (fatsoenlijke) taal is.
.oisyn schreef op vrijdag 10 oktober 2008 @ 11:15:
In andere talen heb je een distinctie tussen references en values, waarbij je een value expliciet moet definieren en je een reference naar een value kunt laten wijzen. Bovendien is er een duidelijk verschil tussen het toekennen van een nieuwe verwijzing aan de reference zelf en een toekenning aan de value waarnaar verwezen wordt.
En dat vraag ik me dus juist af: hoe zit dat bij andere talen? In PHP heeft het toekennen van een expliciete value aan een variabele die een reference is gewoon een unset() nodig. Of die reference nu binnen een codeblok aangemaakt is of niet, doet daar niet veel aan af.
Voutloos schreef op vrijdag 10 oktober 2008 @ 11:22:
[...]
Het probleem van Derick is dat hij echt een raar idee heeft over backward compatibility. Dit wijzigen voorkomt een hele hoop wtf's en breekt geen enkel net script. Knikker het eruit en zeg bij de notes voor PHP 6 dat als je op dit gedrag vertrouwde dat je dan wellicht nog een keertje naar je code wilt kijken. Rare quircks welke alleen gebruikt kunnen worden in rare scripts in stand houden != keeping it simple.
Ik ben het 100% met je eens, maar het lijkt wel alsof de wereld stijgert en 'blasphemy' roept op het moment dat er zich zoiets voordoet, terwijl het eigenlijke euvel een variabele is in een codeblok dat zich niet aan de scope van dat codeblok conformeert. Dat in combinatie met references kan voor een ander resultaat zorgen dan je in gedachten had als je je hier niet van bewust bent.
Voutloos schreef op vrijdag 10 oktober 2008 @ 11:22:
[...]
Nee, dat gedrag is gewoon intuitief. :z MAAR, ;) bij de 2e foreach verwacht je gewoon een echte value en wil je niet bij eventuele eerdere loopjes stil staan. Ja, er is geen loop scope, maar dat betekent nog niet dat huidig gedrag intuitief is.
Assumption is the mother of all ... Als je A verwacht en B krijgt, ga je debuggen om te zien waar er iets aan de hand is dat je over het hoofd had gezien. Dat veel programmeurs niet op de hoogte zijn van de scope-bug, ligt aan het feit dat dit niet gedocumenteerd is en niet conventioneel. Maar dat maakt het nog niet fout. Je kunt hoogstens zeggen dat de documentatie niet deugt op dit punt.
Voutloos schreef op vrijdag 10 oktober 2008 @ 11:22:
Een bug of met tegenintuitief gedrag wordt bij PHP te vaak verklaard met iets dat enkel voor de core devvers boeit 'implementatie was zo makkelijker' of met een cliché opmerking over backwards compatability terwijl het huidige gedrag dusdanig stom is dat geen enkel good practice script erop vertrouwt.
Op die manier kun je magic_quotes_gpc of register_globals ook bugs noemen, terwijl die er met (naar ik vermoed) de beste intenties ingebakken zijn. Dat dat naderhand niet slim bleek te zijn, maakt ze nog geen bugs, aangezien ze wel gewoon functioneren.

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23-06 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zyppora schreef op vrijdag 10 oktober 2008 @ 13:41:
[...]


Dat je een reference eerst moet unsetten voordat je daar een expliciete waarde aan kunt hangen is geen rocket science. De quirk zit'em dan ook in de scope. Het voorbeeld in de bugreport probeert daar voor mijn gevoel een dramatisch verhaal aan te geven, maar het blijft een simpele quirk en als je dat in je achterhoofd houdt, hoeft er echt geen issue van gemaakt te worden en is het triviaal hier op juiste wijze mee om te springen. Dat het een workaround is, ben ik met je eens.
Als je die redenatie aanhoudt hoef je nergens meer over na te denken bij het ontwerp van je taal. Gezien de laatste alinea van je laatste post hamer je imho teveel op de term "bug". Je kan idd stellen dat het geen bug is omdat het werkt volgens de spec (dat die spec dan wel weer het resultaat is van de implementatie laten we dan voor het gemak maar even in het midden). Maar of je het nou een bug noemt of niet, je kan niet ontkennen dat de manier zoals het nu is wat onhandig werkt. Je zegt zelf al dat het een quirk is en dat je een workaround nodig hebt. En dáár gaat het nou juist over in deze discussie, dat de designkeuze onhandig is of dat er op z'n minst niet goed over na is gedacht.
Alleen voor references ;) Niet-references kun je gewoon overschrijven. Maar het is inderdaad niet de beste manier om met codeblokken en diens variabelen om te springen.
Álle variabelen in PHP zijn references. Het punt is dat ze niet altijd naar iets unieks hoeven te wijzen. En er is geen manier om dat uit te vinden, anders dan de hele source doorspitten. Jij zegt "het hoeft niet voor niet-references" (vertaling: het hoeft niet voor variabelen die je nooit naar iets anders hebt laten wijzen). Het probleem is dat het niet direct duidelijk is of dat bij een bepaalde variabele het geval is. Dus vandaar: om defensief te programmeren moet je altijd unsetten.
Ik geef toe dat er wat dat betreft nogal wat aan PHP schort, maar da's een andere discussie vrees ik.
Mwoa, het was niet mijn bedoeling om te stellen dat er iets aan PHP's concept van references schort. Ik legde slechts uit dat het anders in elkaar zit dan ogenlijk vergelijkbare concepten in andere talen.
Ik vraag me af wat functioneel gezien het verschil tussen een reference in PHP en een reference/pointer in een willekeurig andere (fatsoenlijke) taal is.
Zoals ik al zei, alles in PHP is een reference. Alleen bij het eerste gebruik van een variabele zal er een lege slot ergens worden gealloceerd waarnaar verwezen wordt. Assignments aan een variabele veranderen die slot. De =& zorgt ervoor dat de verwijzing van een variabele veranderd naar de slot waar de andere variabele naar verwees.

Neem dit stukje code:
PHP:
1
2
3
4
5
6
$a = 3;
$b = 4;
$b = &$a;
$b = 5;
unset($a);
$a = 6;

$a wordt aangemaakt (stel slot #0 wordt gealloceerd), waaraan 3 wordt geassignd. Dus de 3 staat in #0
Op regel 2 verwijst $b naar #1, met 4 erin.
Dan verwijst $b ook naar #0, dus $b heeft dan de waarde 3, net als $a
Dan wordt 5 geassigned aan $b, dus aan slot #0. De verandering zie je ook terug in $a.
Daarna wordt $a geunset en opnieuw geassigned. $a krijgt dus een verwijzing naar slot #2, met de waarde 6.

Het is foutief om te denken dat $b naar $a wijst op regel 3. Je moet het juist zien als dat $a en $b naar hetzelfde stuk geheugen wijzen. Dit blijkt wel wanneer je $a een andere verwijzing zou meegeven direct na regel 3 - $b verandert dan niet ineens mee.

In C++:
C++:
1
2
3
4
5
6
int *a = new int; *a = 3;  // $a = 3
int *b = new int; *b = 4;  // $b = 4
b = a;                     // $b = &$a
*b = 5;                    // $b = 5
a = NULL;                  // unset($a)
a = new int; *a = 6;       // $a = 6

[ Voor 16% gewijzigd door .oisyn op 10-10-2008 15:31 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23-06 11:51

Janoz

Moderator Devschuur®

!litemod

Zyppora schreef op vrijdag 10 oktober 2008 @ 13:41:
Ik ben het 100% met je eens, maar het lijkt wel alsof de wereld stijgert en 'blasphemy' roept op het moment dat er zich zoiets voordoet, terwijl het eigenlijke euvel een variabele is in een codeblok dat zich niet aan de scope van dat codeblok conformeert. Dat in combinatie met references kan voor een ander resultaat zorgen dan je in gedachten had als je je hier niet van bewust bent.
Het euvel is niet alleen dat. Het euvel is vooral de manier waarop er met dergelijke bug meldingen omgesprongen wordt. En nofi, maar daaraan maak jij je op dit moment ook schuldig. 'Het is niet wat je verwacht , maar als je weet hoe het werkt is het toch logisch?' is een reactie van iemand die er met een code bril naar kijkt. Het punt is dat het een design issue is.
Assumption is the mother of all ... Als je A verwacht en B krijgt, ga je debuggen om te zien waar er iets aan de hand is dat je over het hoofd had gezien. Dat veel programmeurs niet op de hoogte zijn van de scope-bug, ligt aan het feit dat dit niet gedocumenteerd is en niet conventioneel. Maar dat maakt het nog niet fout. Je kunt hoogstens zeggen dat de documentatie niet deugt op dit punt.
Als ik aan een stuur naar rechts draai wil ik dat ik naar rechts ga. Dan kun je documenteren dat het andersom werkt, het verdedigen door te vertellen dat er nu eenmaal een clockwise wormwiel gebruikt is en als handig voorbeeld aandragen dat je bij het achteruitrijden gewoon naar de jusite kant stuurt. Het is volkomen logisch dat het zo werkt door het gebruikte wormwiel, maar maakt dat het ook automatisch logisch dat je naar links moet sturen om rechtsaf te gaan?
Op die manier kun je magic_quotes_gpc of register_globals ook bugs noemen, terwijl die er met (naar ik vermoed) de beste intenties ingebakken zijn. Dat dat naderhand niet slim bleek te zijn, maakt ze nog geen bugs, aangezien ze wel gewoon functioneren.
Iets wordt niet ineens niet slim. Er is niet ineens een moment aan te wijzen waarop register globals ineens niet meer slim was. Het enige wat verandert is het voortschreidend inzicht. Op het moment dat het er uit gehaald is was het net zo fout als het moment dat ze bedacht hebben om het er in te stoppen.

Bijna alle bugs functioneren precies zoals ze gemaakt zijn. Laatst nog had ik een bug in een door mij gemaakt tooltje. Ik moest de datum van gisteren hebben. In de code werd de dag 'gerolled'. Op de eerste van de maand werd echter niet de laatste van de vorige maand genomen, maar de laatste van de huidige maand. Ik had het echter precies zo geprogrammeerd en het functioneerde exact zoals ik het geprogrammeerd had. Dat de dag voor 1 Oktober in mijn applicatie 31 Oktober werd, was dus eigenlijk helemaal geen bug ;).

[ Voor 3% gewijzigd door Janoz op 10-10-2008 16:45 . Reden: Te lange zin 1 woordje korter gemaakt :) ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23-06 23:43

.oisyn

Moderator Devschuur®

Demotivational Speaker

Janoz schreef op vrijdag 10 oktober 2008 @ 15:42:
Als ik aan een stuur naar rechts draai wil ik dat ik naar rechts ga. Dan kun je wel documenteren dat het andersom werkt, het verdedigen door te vertellen dat er nu eenmaal een clockwise wormwiel gebruikt is en als handig voorbeeld aandragen dat je bij het achteruitrijden gewoon naar de jusite kant stuurt. Het is volkomen logisch dat het zo werkt door het gebruikte wormwiel, maar maakt dat het ook automatisch logisch dat je naar links moet sturen om rechtsaf te gaan?
_o_
Wat voor auto is dat, een Zend 307? :P

[ Voor 3% gewijzigd door .oisyn op 10-10-2008 15:56 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 23-06 11:51

Janoz

Moderator Devschuur®

!litemod

.oisyn schreef op vrijdag 10 oktober 2008 @ 15:54:
[...]

_o_
Wat voor auto is dat, een Zend 307? :P
Nee, een Orb Micra ;)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Anoniem: 14829

Gomez12 schreef op donderdag 02 oktober 2008 @ 22:26:
Het is afaik voldoende om sql-injections te voorkomen, alleen afaik is het ook killing voor je dbase om alles op deze manier te doen. Voor een simpele query maakt het niet zoveel uit, maar als je meerdere joins / grotere query's gaat maken wil je toch echt wel 100% gebruik maken van alle indexen en dan gaat het steken...
Tikkie offtopic, maar met geparametriseerde queries kun je in sommige gevallen ook zorgen dat je zorgvuldig aangelegde indexen niet of totaal verkeerd bebruikt worden.

Voorbeeld: ADO.NET.
Wanneer bij (het veelgebruikte en handige) Parameters.AddWithValue() gebruikt, en de value is een string, dan wordt het SqlDbType van die parameter automatisch een nvarchar (unicode). Wanneer de strings in je DB (en indexes) van 't type varchar (ANSI) zijn, kan de database (bij mij MSSQL 2005) eigenlijk niks meer met z'n indexen.
Oplossing is dan zelf een new Parameter() creeren, zelf z'n Name en Value zetten, en 't DbType expliciet op AnsiString of AnsiStringFixedLength zetten (wanneer de kolom in de DB char is i.p.v. varchar), en dan die Parameter aan Parameters te adden.

Dit kan een snelheidswinst van een paar 100 tot meerdere duizenden procenten opleveren, afhankelijk van je tabel, indexen en query.

Acties:
  • 0 Henk 'm!

  • Zyppora
  • Registratie: December 2005
  • Laatst online: 15:30

Zyppora

155/50 Warlock

.oisyn schreef op vrijdag 10 oktober 2008 @ 14:02:
[...]

Als je die redenatie aanhoudt hoef je nergens meer over na te denken bij het ontwerp van je taal. Gezien de laatste alinea van je laatste post hamer je imho teveel op de term "bug". Je kan idd stellen dat het geen bug is omdat het werkt volgens de spec (dat die spec dan wel weer het resultaat is van de implementatie laten we dan voor het gemak maar even in het midden). Maar of je het nou een bug noemt of niet, je kan niet ontkennen dat de manier zoals het nu is wat onhandig werkt. Je zegt zelf al dat het een quirk is en dat je een workaround nodig hebt. En dáár gaat het nou juist over in deze discussie, dat de designkeuze onhandig is of dat er op z'n minst niet goed over na is gedacht.


[...]
Janoz schreef op vrijdag 10 oktober 2008 @ 15:42:
[...]

Het euvel is niet alleen dat. Het euvel is vooral de manier waarop er met dergelijke bug meldingen omgesprongen wordt. En nofi, maar daaraan maak jij je op dit moment ook schuldig. 'Het is niet wat je verwacht , maar als je weet hoe het werkt is het toch logisch?' is een reactie van iemand die er met een code bril naar kijkt. Het punt is dat het een design issue is.


[...]
Jullie slaan in principe beide de spijker op zijn kop: het is een design issue (dat heb ik ook niet echt ontkend, heb ik het idee, maar dat terzijde). Er wordt van een mug een gigantische olifant gemaakt, mede dankzij de manier van reageren van de PHP devvers. Maar het blijft een mug imo. Geen auto die naar links duikt als je naar rechts stuurt, of waarvan het gaspedaal links zit. Meer een auto waarvan de uitlaat naar de zijkant wijst, misschien. Of waarvan de benzinedop onder de spiegel zit (niet de binnenspiegel uiteraard ;) ).

En ja, ik kijk er inderdaad met een code bril naar, en ik haal mijn schouders op wanneer ik tegen zoiets aanloop, en verzin er wat creatiefs op om toch het gewenste resultaat te krijgen. Het is geen ernstig probleem, zoals bijv. print() dat zou zijn als deze ongedocumenteerd code zou uitvoeren (a la exec() of eval() of zo).

Phenom II X4 945 \\ 8GB DDR3 \\ Crosshair IV Formula \\ R9 290


Acties:
  • 0 Henk 'm!

Anoniem: 156876

edit: sorry weet niet waar ik net keek maar dit gaat even heel ergens anders over ... :X

[ Voor 82% gewijzigd door Anoniem: 156876 op 13-10-2008 11:40 ]


Acties:
  • 0 Henk 'm!

Anoniem: 111573

Fraai topic, ik heb het net eens soort van helemaal - 8) - doorgelezen. Als eenvoudige scriptkid die gewoon een leuk wielerspelletje wil maken voor zijn vriendjes - *O* - zou ik graag gewoon een native functie hebben in de phplib die dit probleem aanpakt. (En daar begon de discussie allemaal mee toch?)

Het argument dat iedereen maar gewoon een fatsoenlijke programmeur moet zijn gaat imho maar deels op. PHP is volgens mij van het begin opgezet als toegankelijke scripttaal voor het grote publiek en heeft in grammatica en syntax altijd gestreefd een groot publiek te bereiken. Vanuit die gedachte vind ik het dus niet gek dat er een standaard mysql_safe_query ($sql) zou bestaan.

Om te blijven in de vergelijking van het geweer en de Spijtbetuiging die zichzelf in de voet schiet, er is wel degelijk een veiligheidspal op een geweer. Mensen die weten wat ze doen kunnen de pal eraf halen, Spijtbetuigingen zouden em er graag ophebben.

*edit*
Het aller domste van deze post even verwijderd, de rest van de dommigheid laten staan.

[ Voor 7% gewijzigd door Anoniem: 111573 op 14-10-2008 12:52 ]


Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
Je bedoelt met veiligheidspal toch niet de magic_quotes hoop ik? ;)

March of the Eagles


Acties:
  • 0 Henk 'm!

Anoniem: 111573

Hacku schreef op dinsdag 14 oktober 2008 @ 12:51:
Je bedoelt met veiligheidspal toch niet de magic_quotes hoop ik? ;)
Dat was een hele slechte poging tot iets dergelijks ja. Ik ben het wel met Olaf eens als hij op pagina 1 zegt:
Olaf van der Spek schreef op dinsdag 30 september 2008 @ 16:33:
Het is toch belachelijk dat bijna iedereen die MySQL functies op een veilige manier wil gebruiken eerst zelf een bepaalde functie moet schrijven?
Volgens mij is er onderhand wel aangetoond dat dat gewoon niet werkt, getuige de hoeveelheid kwetsbaarheden.
Als ik zie hoeveel pogingen hier - toch het beste progforum van het Nederlandse taalgebied durf ik te veronderstellen - nodig zijn om tot een bijna safe oplossing te komen, hoe moet ik het als lamzak dan fixen? Ik ben ook allergisch voor categorische oplossingen, daarom moeten ze mysql_query niet standaard safe maken, maar een mysql_safe_query ERBIJ die niet standaard unsafe is zou in mijn geval een hoop ellende schelen denk ik.

Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 16:33

MueR

Admin Tweakers Discord

is niet lief

Nee, dat doet het niet. Je wil dat de PHP developers een functie gaan schrijven die jouw query gaat parsen en vervolgens karakter voor karakter gaat kijken wat hij nou wel of niet moet unescapen. Dat heeft een zo uit mn hoofd al 2 nadelen:
1) Jij leert het nooit, want je blijft een "lamzak". Leer programmeren of stop er nu mee.
2) De performance is stukken slechter als zelf eerst even je query goed opbouwen met escaped vars.

Fatsoenlijk programmeren moet jij doen. PHP is de laatste tijd bezig met een inhaalslag naar de volwassen programmeertalen. Het toegankelijke is leuk, maar gezien de vele idioten die menen te kunnen programmeren is het niet heel verstandig.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • BCC
  • Registratie: Juli 2000
  • Laatst online: 17:57

BCC

Volgens mij hoeven Security en Usability elkaar niet uit te sluiten. Maar voor elke taal geld: je kan altijd 'lekke' code schrijven, maar het is wel erg fijn als de je code niet by default lekken bevat.

[ Voor 49% gewijzigd door BCC op 14-10-2008 13:21 ]

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 10:48

Creepy

Tactical Espionage Splatterer

En er zijn standaard zaken in PHP die het voor je oplossen: de nieuwe mysqli interface met geparametriseerde queries en PDO schijnt dat ook te kunnen. Dat er dan mensen zijn die krampachtig vasthouden aan mysql_query en een functie willen hebben die op precies dezelfde manier werkt maar dan veilig kunnen we verder ook weinig aan doen ;)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
daarom moeten ze mysql_query niet standaard safe maken, maar een mysql_safe_query ERBIJ die niet standaard unsafe is zou in mijn geval een hoop ellende schelen denk ik.
Emz, het werd hier al tig keer geroepen: mysqli en PDO bieden hier een oplossing voor.

March of the Eagles


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Anoniem: 111573 schreef op dinsdag 14 oktober 2008 @ 12:57:
Als ik zie hoeveel pogingen hier - toch het beste progforum van het Nederlandse taalgebied durf ik te veronderstellen - nodig zijn om tot een bijna safe oplossing te komen, hoe moet ik het als lamzak dan fixen?
Nou, reply nummer 2 is safe en volgens best-practice. Reply 1 was niet eens een poging. Het is dus in een keer goed gegaan; ik vind dat best meevallen. :)

Daarna volgden enkel nog best veel mensen die een zogenaamd "betere" oplossing hadden. Niemand houdt je trouwens tegen om toch mysql_query_safe te gaan gebruiken. Ik zou enkel gewoon prepared statements gebruiken.. ;)
MueR schreef op dinsdag 14 oktober 2008 @ 13:11:
2) De performance is stukken slechter als zelf eerst even je query goed opbouwen met escaped vars.
Laat dat argument maar achterwege, want veel processortijd zal het tegenwoordig echt niet kosten... Bovendien heeft prepared statements mijn voorkeur boven opbouwen. :)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
nieuws: Hacker kraakt Kaspersky-website met sql-injectie

Ik vraag me toch nog even af, al die mensen die hier hebben gepost dat een betere standaard functie niet nodig is, gebruiken die inderdaad wel hun eigen veilige wrapper of gebruiken ze stieken toch direct mysql_query in combinatie met mysql_real_escape_string?
En hoe zeker zijn die ervan dat al hun code geen SQL lek bevat?

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Olaf van der Spek schreef op maandag 09 februari 2009 @ 14:51:
nieuws: Hacker kraakt Kaspersky-website met sql-injectie

Ik vraag me toch nog even af, al die mensen die hier hebben gepost dat een betere standaard functie niet nodig is, gebruiken die inderdaad wel hun eigen veilige wrapper of gebruiken ze stieken toch direct mysql_query in combinatie met mysql_real_escape_string?
En hoe zeker zijn die ervan dat al hun code geen SQL lek bevat?
Shit happens gewoon; overal worden fouten gemaakt en als je een keer een steekje laat vallen en je bent een hoge boom... tja, dan vang je veel wind. Natuurlijk is er geen excuus voor dat zoiets kan gebeuren (zeker bij bedrijven als Kapersky) maar in de praktijk kan het natuurlijk altijd voorkomen dat een stagiair een pagina geknutseld heeft of weet-ik-wat en dat niet is opgemerkt door evt. controlerende afdelingen etc. En tja, dan ga je nat. Shit happens. Live with it. Het is gewoon realistisch dat zoiets zo nu en dan gebeurt. Daarom zijn backups ook zo belangrijk.

Nee, het mag niet gebeuren. Ja, controle hoort er te zijn. Ja, zéker als er god-knows-what voor gegevens potentieel op straat kunnen komen liggen. Nee, ik probeer het niet recht te lullen. Ja, shit happens.

[ Voor 8% gewijzigd door RobIII op 09-02-2009 14:56 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
RobIII schreef op maandag 09 februari 2009 @ 14:55:
Shit happens gewoon; overal worden fouten gemaakt en als je een keer een steekje laat vallen en je bent een hoge boom... tja, dan vang je veel wind.
Dat is eigenlijk het punt van dit topic. Ja, een foutje kan gebeuren. Maar nee, een single point of failure is niet goed. Zo'n foutje mag gewoon niet leiden tot een (SQL) lek.
Niet als je inderdaad een structurele oplossing daarvoor had.

Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 27-05 16:00

curry684

left part of the evil twins

De Challenger explodeerde ook door een programmeerfoutje. Was ook geen excuus om iedere programmeertaal ter wereld inherent te beschermen met mechanismes om te voorkomen dat je er space shuttles mee kon opblazen.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Knaak
  • Registratie: Juni 2006
  • Laatst online: 24-06 11:18

Knaak

It's me, Mario!

Ik heb zelf een variable class die op allerlij manier variablen kan filteren. Alle data die via GET of POST word opgehaald gaat hier eerst doorheen voordat het in de query beland.

Wat de class eigenlijk doet:
checken op INT
checken op Array > als het een array is > strip deze dan van alle overbodige tekens.

Daarnaast zijn er nog tal van andere functies die o.a. kijken of de variable wel een waarde bevat etc. :)
Zelf nooit problemen gehad met SQL injection, natuurlijk is en blijft het een punt van aandacht voor iedere developer.
Pagina: 1 2 3 4 Laatste

Dit topic is gesloten.