Autor Zpráva
XolyCZ
Profil
Ahoj, nedávno jsem tu měl udělané vlákno kvůli tomu, jestli mám udělaný bezpečně sql dotaz. Teď to píšu jiným způsobem a tak se ptám, jestli to mám dobře nebo ne. Nevím totiž, jak doslova ty dva příkazy spolu pracují. Používám tenhle kód a tak mě napadá, jestli by u toho $_GET['$novinka'] nemělo být ještě htmlspecialchars($_GET['$novinka'], ENT__QUOTES) a posílat to jako parametr do té funkce. Nebo to stačí jenom takhle? Ta novinka označuje ID té novinky..

function showNew($pdo, &$message){
            $stmt = $pdo->prepare("SELECT * FROM novinky WHERE novinky_id=?");
            $stmt->execute([$_GET['novinka']]);
            $new = $stmt->fetch();
            $stmt = null;
        
        if(empty($new)){
            $message="Novinku se nepodařilo načíst.";
            return false;
        }
        
        return $new;
    }


Četl jsem třeba tohle, ale nevím pořádně co z toho použít, protože jsem toho ještě tolik za tu dobu nenapsal, tak se ptám někoho zkušenějšího.. Are PDO prepared statements sufficient to prevent SQL injection?

Při vytváření spojení s databází používám tohle..
session_start();

$dsn = "mysql:host=...;dbname=...;charset=utf8";
$options = [
  PDO::ATTR_EMULATE_PREPARES   => false, // turn off emulation mode for "real" prepared statements
  PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION, //turn on errors in the form of exceptions
  PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //make the default fetch be an associative array
];
try {
  $pdo = new PDO($dsn, "...", "...", $options);
} catch (Exception $e) {
  error_log($e->getMessage());
  exit('Something weird happened'); //something a user can understand
}
DarkMeni
Profil
Vzhledem k SQL injection útoku je to bezpečný. Edit: pokud používáš utf8mb4

Pokud by ses chtěl vyhnout Warningu nebo Uncaught exception v pripde ze se tam pokusí někdo zadat něco jiného nez číslo, tak to můžeš převést přes intval
$stmt->execute( [intval($_GET['novinka'])] );

htmlspecialchars zde není potřeba, to se používá spíš při výpisech pro ochranu před XSS
XolyCZ
Profil
Takže mám ten charset změnit jo? Já jsem o tom kdysi četl, že utf8, databázové, pojme jenom 3 bity na "slovo" nebo jak to popsat a normální utf8 pojme 4. Jak je to dál, to nevím.
DarkMeni
Profil
Podle mě je nejlepší v tomto případě použít intval, pak se o nějaký útok kvůli charsetu nemusíš starat.

Pokud bude potřeba použít vstup od uživatele ve formě řetězce, například pro vyhledávání, tak správně nastavit charset, např. v dsn, což máš (a samozřejmě použít prepared statement nebo quote)
Takže: ne, nemusíš měnit charset na utf8mb4, klasický utf8 je taky v pohodě, v tom útoku který je zmíněný v odkazu co jsi sem dal šlo o to, že byl nesprávně nastavený charset - pro DB se příkazem nastavil na gbk ale na straně serveru byl pořád utf8, takže to PDO escapovalo podle utf8, příkaz se předal DB, ale tam se převedl na gbk a zanky, které byly v utf8 neškodné, se v gbk staly třeba apostrofy.
XolyCZ
Profil
Už to chápu, díky moc :)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0