sql >> Databáze >  >> RDS >> Mysql

Mohu použít PDO připravený příkaz k navázání identifikátoru (název tabulky nebo pole) nebo klíčového slova syntaxe?

Mohu použít příkaz připravený s PDO k navázání identifikátoru (název tabulky nebo pole) nebo klíčového slova syntaxe?

Bohužel, připravený výpis může představovat pouze datový literál. Velmi častým úskalím je tedy dotaz jako tento:

$opt = "id";
$sql = "SELECT :option FROM t WHERE id=?";
$stm  = $pdo->prepare($sql);
$stm->execute(array($opt));
$data = $stm->fetchAll();

V závislosti na nastavení PDO bude tento dotaz mít za následek buď chybu (v případě použití skutečných připravených příkazů) nebo pouze doslovný řetězec 'id' v sadě polí (v případě emulovaných příprav).

Vývojář se tedy musí o identifikátory postarat sám - PDO nenabízí žádnou pomoc pro tuto záležitost.

Aby byl dynamický identifikátor bezpečný, je třeba dodržovat 2 přísná pravidla:

  • správně naformátovat identifikátor
  • pro ověření proti pevně zakódované bílé listině .

Chcete-li naformátovat identifikátor, musíte použít tato 2 pravidla:

  • Uzavřete identifikátor do zpětných značek.
  • Unikněte zpětným tahům dovnitř tím, že je zdvojnásobíte.

Po takovém formátování je bezpečné vložit do dotazu proměnnou $table. Kód by tedy byl:

$field = "`".str_replace("`","``",$field)."`";
$sql   = "SELECT * FROM t ORDER BY $field";

I když by však takové formátování stačilo pro případy jako ORDER BY, pro většinu ostatních případů existuje možnost jiného druhu injekce:když necháme uživatele vybrat si tabulku nebo pole, které vidí, můžeme odhalit citlivé informace, jako je heslo nebo jiné osobní údaje. Vždy je tedy lepší porovnat dynamické identifikátory se seznamem povolených hodnot. Zde je krátký příklad:

$allowed = array("name","price","qty");
$key     = array_search($_GET['field'], $allowed);
$field   = $allowed[$key];
$query   = "SELECT $field FROM t"; //value is safe

Pravidla pro klíčová slova jsou stejná, ale samozřejmě není k dispozici žádné formátování – je tedy možné a mělo by se používat pouze přidávání na seznam povolených:

$dir = $_GET['dir'] == 'DESC' ? 'DESC' : 'ASC'; 
$sql = "SELECT * FROM t ORDER BY field $dir"; //value is safe

Podívejte se také na tuto poznámku přidanou uživatelem v dokumentaci PHP:Uživatelská poznámka k PDO::quote




  1. 4 způsoby, jak vložit více řádků do Oracle

  2. Připojení 64bitové aplikace k Acombě

  3. Jakou velikost používáte pro varchar (MAX) v deklaraci parametru?

  4. Jak spustit makro z navigačního tlačítka v aplikaci Access