Python týden Geek tričko zdarma
Tričko zdarma! Stačí před dobitím bodů použít kód TRIKO15. Více informací zde
Pouze tento sleva až 80% na kurzy Python

Diskuze: Nelze vložit do databáze - Fatal error

Aktivity (1)
Avatar
Honza
Člen
Avatar
Honza:3. ledna 22:48

Ahoj, když chci do databáze zapsat proměnné, které získám z html formuláře tak mi to neustále hází error:

Fatal error: Uncaught Error: Call to a member function execute() on bool in D:\xampp\htdoc­s\Web\Db.php:61 Stack trace: #0 D:\xampp\htdoc­s\Web\Db.php(81): Db::executeSta­tement(Array) #1 D:\xampp\htdoc­s\Web\info.php(12): Db::querySingle('SE­LECT uzivatel...') #2 {main} thrown in D:\xampp\htdoc­s\Web\Db.php on line 61

**Používám zdejší Db wrapper a moje info.php vypadá takto: **
<?php
session_start();
require("Db.php");
$Db = Db::connect("lo­calhost", "uzivatele", "root", "");

$uzivatel = $_GET['uzivatel_id'];
$luckynum = $_POST['luckynum'];
$vek = $_POST['vek'];
$tel = $_POST['tel'];

$existuje = Db::querySingle("SE­LECT uzivatel_id FROM uzivatele WHERE uzivatel_id = {$uzivatel}");

if($existuje) {
Db::query('INSERT INTO uzivatelinfo (uzivatel, luckynum, vek, tel) VALUES ("$uzivatel"), ("$luckynum"), ("$vek"), ("$tel")');
}

?>

Zkusil jsem: Googlil jsem tento error, bohužel nic nepomohlo...

Díky moc,
Honza

Editováno 3. ledna 22:49
 
Odpovědět 3. ledna 22:48
Avatar
Odpovídá na Honza
Michal Štěpánek:4. ledna 7:25

Nedělám v PHP, ale podle mě máš "obráceně" podmínku, protože uživatele bys měl vkládat pokud neexistuje.
A ty závorky za tím VALUES bych taky vyhodil

Db::query('INSERT INTO uzivatelinfo (uzivatel, luckynum, vek, tel) VALUES ($uzivatel, $luckynum, $vek, $tel)');
Nahoru Odpovědět 4. ledna 7:25
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Michal Štěpánek
Michal Štěpánek:4. ledna 7:27

Teď jsem si všiml, že toho uživatele vkládáš do jiné tabulky, pak je ta podmínka asi dobře...

Nahoru Odpovědět 4. ledna 7:27
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:4. ledna 10:28
Error: Call to a member function execute() on bool in D:\xampp\htdocs\Web\Db.php:61

To znamena, ze na nekterem radku predtim provedes neco spatne. Vznikne v promene hodnota boolean. A ta neni kompatibilni s funkci na aktualnim radku. Funkce ocekavala treba sql-resource typ a ne boolean.


$uzivatel = $_GET['uzivatel_id'];
Db::querySingle("SELECT uzivatel_id FROM uzivatele WHERE uzivatel_id = {$uzivatel}");

Tohle budu delat, ze jsem jako vubec nevidel nebo by se mi desem a hruzou zjezili vsechny vlasy a nekolik dni bych nespal :)

1. Hele, kdyz prebiras data od ouzivatele, musis provest jejich kontrolu! Nesmis je primo pouzit do sql prikazu. zkus si tam do kolonky uzivatel vlozit:
"1 OR 1=1"
Co se stane ted? Prihlasi mne na prvniho uzivatele z tabulky uzivatel.
Co se stane pak? Prvni radek z tabulky obvykle byva superadmin. Co by se pak asi mohlo stat, ze?
2. Do sql prikazu nemuzes davat ani zkontrolovana data jen tak. Ja na to pouzivam funkci escapeSql, ktera to resi jinou funkci. Netusim vsak, jake prikazy sql se volaji z tve class Db.php, takze ti nemuzu poradit, co s tim. Napr by to vypadalo takto

function escapeSqlValue($value) {return mysql_real_escape_string($value);}
Db::querySingle("SELECT uzivatel_id FROM uzivatele WHERE uzivatel_id = ".escapeSqlValue($uzivatel)."");

3. Sql rozlisuje mezi tim, kdy mu zadavas string a integer. Muze a nemusi to udelat totez.

SELECT uzivatel_id FROM uzivatele WHERE uzivatel_id=123
SELECT uzivatel_id FROM uzivatele WHERE uzivatel_id='123'

Hack, pokud neosetris vstup uzivatele vypada takto
"1 OR 1=1" nebo
"1' OR '1'='1"

SELECT uzivatel_id FROM uzivatele WHERE uzivatel_id=1 OR 1=1
SELECT uzivatel_id FROM uzivatele WHERE uzivatel_id='1' OR '1'='1'

Jo, a mozna by ti pomohlo, kdyby sis zobrazil sql prikaz, ktery se pokousis podstrcit databazi. Treba pomoci echo $query nebo var_dump($query) ve funkci Db::querySingle

Editováno 4. ledna 10:30
 
Nahoru Odpovědět 4. ledna 10:28
Avatar
Honza
Člen
Avatar
Odpovídá na Peter Mlich
Honza:4. ledna 17:17

Zdravím, tak jsem se dočetl, že kvůli bezpečnosti se tam také dávají místo proměnnýho otazníky a až pak proměnné, což nechápu proč když tam tu proměnnou dosadim stejně potom místo toho otazníku, ale najednou to funguje :D
if($existuje) {
Db::query('INSERT INTO uzivatelinfo (uzivatel, luckynum, vek, tel) VALUES (?, ?, ?, ?)', $uzivatel, $luckynum, $vek, $tel);
}

Jinak s tím hackem díky za tip! Zkusím to nějak ověřit a zamezit tomu.

 
Nahoru Odpovědět 4. ledna 17:17
Avatar
Odpovídá na Honza
Matúš Olejník:4. ledna 18:40

Je to preto aby si zabránil tzv. SQL injections, pretože ak by ti niekto napr. ako telefón zadal celý tento string "123); DROP TABLE uzivatelinfo; --" tak by z tvojho kódu vznikli dva príkazy

INSERT INTO uzivatelinfo (uzivatel, luckynum, vek, tel) VALUES (1, 3, 24, 123);
DROP TABLE uzivatelinfo; --)'

čím by ti vymazal celú tabuľku.

Keď to spravíš tým druhým spôsobom, že použiješ prepared statements sa query najprv skompiluje s tým, že namiesto zadaných dát od užívateľa sú ? a následne pred vykonaním sa tieto otázniky nahradia tým čo zadal čiže už nie je čas na to, že by sa query skompilovala ako dva príkazy.

Pekné príklady rôznych útokov si môžeš pozrieť tu
A niečo o prepared statements tu a tu

Nahoru Odpovědět  +1 4. ledna 18:40
/* I am not sure why this works but it fixes the problem */
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 6 zpráv z 6.