1

私は現在、セキュリティに重点を置いた php フレームワークを作成しています。MySQL にバインドされないように、クエリ ビルダーを使用して SQL ステートメントを生成します。(またはSQL全般)ユーザーが行名を挿入できる特定の可能性を見つけたので、何らかの方法でそれらをエスケープする必要があります。クエリ ビルダーの仕組みが原因で、残念ながら準備済みステートメントを使用できません。どうすればこれを修正できますか?

編集:

システムは、たとえば次のように機能しますdb::select()-from('Tablename')->that('rowname')->run()。そして、1人のユーザーが何かのようなことをすることができるのではないかと心配していますthat($_GET['foo']). 私はそれで暮らすことができましたが、これをサナタイズする方法が必要だと思いました

4

2 に答える 2

0

バックティックをエスケープするには、2 倍にする必要があります。ここに私のクラスの関数があります

private function escapeIdent($value)
{
    if ($value)
    {
        return "`".str_replace("`","``",$value)."`";
    } else {
        $this->error("Empty value for identifier (?n) placeholder");
    }
}

//example:
$db->query("UPDATE users SET ?u=?s", $_POST['field'], $_POST['value']);

したがって、構文的に正しい識別子が作成されます。

ただし、正しい名前であっても、ユーザーがアクセス権を持たないフィールドが存在する可能性があるため、常にホワイトリストに登録することをお勧めします。(したがって、スキーマベースのソリューションは、この観点からは依然として危険です。私の例のクエリのrole値を持つフィールドがあると想像してください) この目的のためにクラスに2つの関数があり、どちらも許可された値の配列を受け入れます。admin

于 2013-02-15T18:07:05.353 に答える
-1

クエリ ビルダーの仕組みが原因で、残念ながらプリペアド ステートメントを使用できません。どうすればこれを修正できますか?

クエリ パラメーターを使用できない場合は、SQL 式に補間する前に引数にエスケープを適用するようにクエリ ビルダーを変更します。

多くの人がクエリ パラメーターを正しく推奨していますが、正しく一貫してエスケープを実行すれば、エスケープも安全です。

参照。mysqli::real_escape_string()


あなたのコメントについて、わかりました。あなたが「行名」と言ったので混乱しましたが、それは正しい用語ではありません。列名を意味する必要があります。

はい、その通りです。どの MySQL API にも、テーブルまたは列の識別子を正しくエスケープする関数はありません。エスケープ関数は、文字列リテラルと日付リテラル専用です。

信頼できない入力がテーブルまたは列に名前を付ける場合に SQL クエリを保護する最善の方法は、ホワイトリストを使用することです。つまり、既知のテーブル名または列名のリストに対して引数をテストします。これらは手動でコーディングするか、DESCRIBE table.

私の過去の回答でホワイトリストの例を参照してください。

于 2013-02-15T16:50:55.253 に答える