PDO gigatische error

  • weer iets waarover ik mijn hersenen ben aan het breken:


    de error is hier te bezichten.


    Hopelijk kan iemand mij helpen want ik zou niet weten wat ik fout gedaan heb.

  • Guest, wil je besparen op je domeinnamen? (ad)
  • Verander eens dit:

    Code
    $result = $db->prepare("SELECT * FROM faucets ORDER BY :sorton :order");
    $result->bindValue(':sorton', $sorton, PDO::PARAM_STR);
    $result->bindValue(':order', $order, PDO::PARAM_STR);
    $result->execute();


    In dit:

    Code
    $result = $db->prepare("SELECT * FROM faucets ORDER BY :sorton :order");
    $result->execute(array(':sorton' => $sorton, ':order' => $order));

    Vervolgens, zorg dat $sorton effectief een tabel attribuut bevat en dat $order ook juist is LIMIT *,* ...
    Ik heb nooit eerder tabel attributen of orders gebind, snap ook niet waarom dat nodig is zolang het geen user input is.
    Dus alsnog indien geen user input of op z'n minst door jouw samengestelde input variabelen a.h.v. die user input: dan kan je zonder gebinde parameters werken in je querie:

    Code
    $result = $db->prepare("SELECT * FROM faucets ORDER BY `$sorton` $order");
    $result->execute();


    PS op die pagina lijken de errors uit een ander script te komen.
    Illegal string offset komt voor wanneer je array ongeldige keys of values bevat, een oplossing kan zijn $arr = array("var" => $var); //Werken met dubbele quotes

  • Toevoeging op code van @MiCa-

    PHP
    $result = $db->prepare("SELECT * FROM faucets ORDER BY `$sorton` $order");
    $result->execute();

    Hiermee doe je het idee van prepared statement min of meer teniet (door rechtstreeks waarden in je querystring te plakken in plaats van te binden via parameters of values).


    Helaas is het niet mogelijk om dit op een andere manier te doen omdat het simpelweg niet mogelijk is om tabelnamen en -kolommen te binden op deze manier (of extra SQL te schrijven, for that matter). Daarvoor zijn prepared statements niet bedoeld, het is enkel de bedoeling dat je DATA bind, en niets anders.


    Met het bovenstaande introduceer je wel weer de mogelijkheid voor SQL injectie. Omdat je de spelregels van prepared statements met bovenstaande constructie omzeilt is je query hier weer vatbaar voor. Zorg dus dat je met whitelists werkt, oftewel definieer wat toegestane waarden zijn voor $sorton en $order en zorg ervoor dat ze terug kunnen vallen op een geldige (en zinnige) default waarde.


    (Hetgeen in de vorige alinea wordt beschreven komt in wezen neer op input filtering)

  • Ik bedoelde, wanneer jij zelf de tabel kolommen valideert en je order string ook netjes valideerd a.h.v. enige input dan kan je perfect deze variabelen in je query toevoegen zonder dat iemand daarop kan inspelen. Data zoals jij aangeeft aan de andere kant moet wel steeds gebind worden en daarvoor beveel ik het 2e stukje code aan in mijn eerdere post i.p.v. iedere parameter in een aparte lijn te gaan binden. Data zal meestal ook alleen maar voorkomen in de WHERE clause.


    Kolommen valideren kan al met een simpele array met toegankelijke kollomen, en je order kan gwn a.h.v. je gebruikers input, switch die en maak je string op met int waarden indien user input geen int waarde is stel je gwn een standaar in zoals bv: LIMIT 0,10
    Dit is vooral handig bij dynamische code, functies die op meerdere vesrch wijzen gebruikt kunnen worden. Het is veilig zolang je weet wat je doet..

  • pff. ik heb er echt een zootje van gemaakt geen enkel van bovenstaande werkt.


    de volledige pagina:

  • Mja, als de maan van kaas is ben ik Napoleon.
    Met andere woorden: als je uitgangsstelling niet klopt kun je zeggen wat je wilt (false => true).


    Getuige bovenstaande code van @ruttydm, die zo lek is als maar kan zijn.

    als het niet klopt genereer je een default of een error message om de gebruiker er op te wijzen..
    Tenslotte is het de programmeur die bepaald wat de code moet doen en niet de gebruiker, daarmee moet de programmeur altijd rekening houden.


    Het is zeker niet verkeerd om ALTIJD je query input te gaan binden, maar het is ook gewoon niet altijd nodig, gebruikers input zonder enige validatie moet gewoon altijd gebind worden om inderdaad injectie tegen te gaan.


  • Tenslotte is het de programmeur die bepaald wat de code moet doen en niet de gebruiker, daarmee moet de programmeur altijd rekening houden.

    Helaas is het tegenwoordig meer de gebruiker die bepaald hoe een product gebruikt wordt dan andersom. Als programmeur moet je daarom input van gebruikers nooit, maar dan ook nooit vertrouwen!


    Verder ben ik het compleet met je opmerking eens MiCa-!

  • Ik heb het gefixt, ik hzb gebruik gemaakt van whitelists en deze code:

  • Het is zeker niet verkeerd om ALTIJD je query input te gaan binden, maar het is ook gewoon niet altijd nodig, gebruikers input zonder enige validatie moet gewoon altijd gebind worden om inderdaad injectie tegen te gaan.

    Sterker nog, het *kan* niet altijd, en dat is hier juist het probleem. Zoveel stond al in mijn eerste reactie.


    Vervolgens begint de discussie een beetje te vervagen met wat de rol van een programmeur en een gebruiker zou zijn. Ik heb sinds mijn eerste reactie eigenlijk geen nieuwe relevante informatie ten aanzien van dit topic de revue zien passeren.


    De topicstarter moet gewoon alle input die niet via prepared statements verloopt filteren, te meer omdat deze rechtstreeks uit $_GET lijkt te komen.


    Hoe je vervolgens fouten afvangt (of je nu een foutmelding produceert -wat niet erg gebruiksvriendelijk is- of terugvalt op een default waarde) is uitwerking / zijn details, en heeft ook weinig van doen met het oorspronkelijke probleem. Het oorspronkelijke probleem was dat de topicstarter iets probeerde te binden wat niet gebind kon worden. Vervolgens geef ik aan:


    - dat / waarom dit niet altijd kan
    - hoe je dit dan wel doet
    - en waar je daarbij op moet letten


    Volgens mij kun je geen vollediger antwoord dan dat geven, behalve misschien dat je ook de complete oplossing uitschrijft. Maar als je dat (in dit eenvoudige geval) niet zelf kunt, dan zou je deze tak van sport niet moeten bedrijven.


    @ruttydm uit jouw code kan niet opgemaakt worden hoe $sorton en $order "veilig gemaakt" zijn.

  • @ruttydm dat werkt niet zoals je wellicht zou denken.


    Als je voor $sorton bijvoorbeeld "reward_hour" invult (wat een toegestane waarde is) dan wordt sorton toch gelijk aan "average_reward".


    Je if-statement klopt niet. Je hebt daar namelijk staan ... or "<niet lege string>" or ... . Dat is altijd waar, waardoor het if-statement in zijn geheel ook altijd waar is. Een controle met in_array lijkt mij beter dan deze (niet-kloppende) constructie.

  • Is dit dan goed?
    Alleen is mijn site supertraag geworden.


    edit: site is traag omdat ik externe locatie gebruik voor bootstrap

  • Ik zou het zo doen, het is (iets) korter, meer to-the-point en meer in lijn met een whitelist:


    Al doet het syntactisch waarschijnlijk hetzelfde als jouw codefragment vind ik deze toch wat prettiger lezen. Het doet ook precies wat het moet doen, niet meer, niet minder.

Participate now!

Heb je nog geen account? Registreer je nu en word deel van onze community!