sql >> Databasteknik >  >> RDS >> Mysql

undvika MySQL-injektioner med Zend_Db-klassen

Jag skrev mycket av koden för databasparametrar och citerade i Zend Framework medan jag var teamledare för projektet (upp till version 1.0).

Jag försökte uppmuntra bästa praxis där det var möjligt, men jag var tvungen att hitta en balans med enkel användning.

Observera att du alltid kan undersöka strängvärdet för en Zend_Db_Select invända, för att se hur den har beslutat att göra citering.

print $select; // invokes __toString() method

Du kan också använda Zend_Db_Profiler för att inspektera SQL som körs för din räkning av Zend_Db .

$db->getProfiler()->setEnabled(true);
$db->update( ... );
print $db->getProfiler()->getLastQueryProfile()->getQuery(); 
print_r $db->getProfiler()->getLastQueryProfile()->getQueryParams(); 
$db->getProfiler()->setEnabled(false);

Här är några svar på dina specifika frågor:

  • Zend_Db_Select::where('last_name=?', $lname)

    Värden anges på lämpligt sätt. Även om "? " ser ut som en parameterplatshållare, i den här metoden citeras argumentet faktiskt på lämpligt sätt och interpoleras. Så det är inte en sann frågeparameter. I själva verket producerar följande två satser exakt samma fråga som ovanstående användning:

    $select->where( $db->quoteInto('last_name=?', $lname) );
    $select->where( 'last_name=' . $db->quote($lname) );
    

    Men om du skickar en parameter som är ett objekt av typen Zend_Db_Expr , då citeras det inte. Du är ansvarig för SQL-injektionsrisker, eftersom det är interpolerat ordagrant, för att stödja uttrycksvärden:

    $select->where('last_modified < ?', new Zend_Db_Expr('NOW()'))
    

    Alla andra delar av uttrycket som behöver citeras eller avgränsas är ditt ansvar. Om du till exempel interpolerar några PHP-variabler i uttrycket är säkerheten ditt ansvar. Om du har kolumnnamn som är SQL-nyckelord måste du själv avgränsa dem med quoteIdentifier() . Exempel:

    $select->where($db->quoteIdentifier('order').'=?', $myVariable)
    
  • Zend_Db_Adapter_Abstract::insert( array('colname' => 'value') )

    Tabellnamn och kolumnnamn är avgränsade, såvida du inte stänger av AUTO_QUOTE_IDENTIFIERS .

    Värden parametriseras som sanna frågeparametrar (inte interpolerade). Om inte värdet är en Zend_Db_Expr objekt, i vilket fall det interpoleras ordagrant, så du kan infoga uttryck eller NULL eller vad som helst.

  • Zend_Db_Adapter_Abstract::update( array('colname' => 'value'), $where )

    Tabellnamn och kolumnnamn är avgränsade, såvida du inte stänger av AUTO_QUOTE_IDENTIFIERS .

    Värden parametriseras, såvida de inte är Zend_Db_Expr objekt, som i insert() metod.

    $where argumentet filtreras inte alls, så du är ansvarig för eventuella SQL-injektionsrisker i den. Du kan använda quoteInto() metod för att göra det lättare att citera.



  1. Finns det nackdelar med att använda en generisk varchar(255) för alla textbaserade fält?

  2. Hur kan jag ställa in mysqls lösenord i scenariot mysqld_safe körs?

  3. MYSQL lagrad procedur för uppdateringsvariabler är 0

  4. Hur väljer man snabbt 3 slumpmässiga poster från en 30k MySQL-tabell med ett where-filter med en enda fråga?