14

現在、Zend_Db を使用してクエリを管理しています。以下のようなクエリを実行するコードを既に書いています。

$handle->select()->from('user_id')
                   ->where('first_name=?', $id)
                   ->where('last_name=?', $lname)

Zend_Db がサニタイズすると仮定して、入力をサニタイズせずにこれを行いました。Zendはこれを行いますか?

別の質問: Zend_Db はサニタイズinsert('table', $data)updateクエリを実行しますか?

ありがとう。

4

7 に答える 7

24

プロジェクトのチーム リーダーを務めていたとき (バージョン 1.0 まで)、Zend Framework でデータベース パラメーターと引用符のコードを大量に作成しました。

可能な限りベスト プラクティスを奨励しようとしましたが、使いやすさとのバランスを取る必要がありました。

Zend_Db_Selectオブジェクトの文字列値をいつでも調べて、引用 符を付ける方法を確認できることに注意してください。

print $select; // invokes __toString() method

Zend_Db_Profilerを使用して、 が代わりに実行する SQL を検査することもできますZend_Db

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

特定の質問に対するいくつかの回答を次に示します。

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

    値は適切に引用されています。" ?" はパラメーターのプレースホルダーのように見えますが、このメソッドでは、実際には引数が適切に引用され、補間されます。したがって、これは真のクエリ パラメータではありません。実際、次の 2 つのステートメントは、上記の使用法とまったく同じクエリを生成します。

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

    ただし、 type のオブジェクトであるパラメーターを渡す場合Zend_Db_Expr、それは引用符で囲まれません。SQL インジェクションのリスクは、式の値をサポートするために逐語的に補間されるため、責任があります。

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

    引用または区切りが必要な式のその他の部分は、ユーザーの責任です。たとえば、PHP 変数を式に挿入する場合、安全性はユーザーの責任です。SQL キーワードである列名がある場合は、それらを で区切る必要がありますquoteIdentifier()。例:

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

    をオフにしない限り、テーブル名と列名は区切られますAUTO_QUOTE_IDENTIFIERS

    値は真のクエリ パラメータとしてパラメータ化されます (補間されません)。Zend_Db_Expr値がオブジェクトでない限り、その場合は逐語的に補間されるため、式などを挿入できますNULL

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

    をオフにしない限り、テーブル名と列名は区切られますAUTO_QUOTE_IDENTIFIERS

    Zend_Db_Exprメソッドのように、値がオブジェクトでない限り、値はパラメーター化されinsert()ます。

    引数はまったくフィルター処理されないため、その$where引数での SQL インジェクションのリスクについてはユーザーが責任を負います。この方法を利用すると、quoteInto()引用がより便利になります。

于 2009-06-12T06:50:54.333 に答える
5

はい。http://framework.zend.com/manual/en/zend.db.select.htmlを参照してください。心配しないで。あなたが懐疑的であるのは正しいです。

于 2009-06-10T11:36:05.190 に答える
2

次のように SQL クエリで値バインディングを使用すると、デフォルトで次のようになります。

where('first_name=?', $id);

Zend_Db は、値の適切な引用符を使用して SQL インジェクションを防ぎます。ただし、ユーザー入力をサニタイズ/フィルター処理することを強くお勧めします (本、記事、マニュアル、および自己経験による)。Zend_Filterは非常に役立ちます。

于 2009-06-10T17:41:42.503 に答える
1

他の場所(結合など)で必要な場合、またはエスケープされるかどうかわからない場合は、いつでも使用できます$this->getAdapter()->quoteInto('type = ?',1);

于 2009-06-10T17:17:48.557 に答える
1

あなたが安全だと感じるはずのビットは?where句のマーク。これらはパラメータであり、データベース システムによって安全に 2 番目の引数に置き換えられます。

于 2009-06-10T16:25:34.700 に答える
0

入力のフィルタリングは常に適切です。なぜなら、入力は DB 以外の場所に移動する可能性が高く、少なくともあるレベルでデータベースに適切なデータが必要だからです。

  • Zend_Filter_Input途中で
  • 準備されたステートメント (準備されていない場合は quoteInto)
  • 途中でフィルターをエスケープします (htmlentities など)。
于 2009-06-10T20:59:42.570 に答える
0

これに関する1つのことは、値がNULLの場合、無効なクエリを達成できます

$value = NULL;
$select->where('prop=?', $value);

結果: SQL エラー

于 2009-06-11T16:49:53.357 に答える