5

これは私の最初の投稿であり、プログラミングの世界にも比較的慣れていません。簡単に言うと、php、mysql、および javascript/jquery を使用して開発した e コマース サイトを完成させているときに、すべてのクエリを (mysql_connect を使用して) 構築していた方法が、mysql インジェクションやその他の多くの厄介な問題につながる可能性があることを発見しました。もの。

すべてをより安全なmysqliで準備されたステートメントの方法に「変換」しようとして、データベースから情報を取得するために必要なすべてのメソッドを含むクラスを作成しましたが、作成方法についてはわかりませんクエリ。

いくつかのコード: クラス コンストラクター

class Database {

    private $DBH;

    public function __construct() {
        $this->DBH = new mysqli(WEB_SERVER, WEB_USER, WEB_PASS, WEB_NAME);
        if ($this->DBH->connect_errno) {
            return "Failed to connect to MySQL: (" . $this->DBH->connect_errno . ") " . $this->DBH->connect_error;
            exit();
        }
    }
    ...
}

...そしてクエリの例:

public function get_record_by_param($record, $param, $value) {
    $stmt = $this->getDBH()->stmt_init();

    $query = "SELECT * ";
    $query .= "FROM {$record} ";
    $query .= "WHERE {$param} = {$value} LIMIT 1";

    if($stmt->prepare($query)){
        return $this->execute_simpleAssoc($stmt);
    } else {
    return "Prepare failed: (" . $this->getDBH()->errno . ") " . $this->getDBH()->error;
    }
}

このようなクエリを使用しても安全ですか? または、必ず bind_param メソッドを使用する必要がありますか?

混乱していないことを願って、アドバイスをありがとう。

4

2 に答える 2

3

いいえ、安全ではありません。mysqli は、クエリ文字列内の (潜在的に脆弱な) データとそうでないものを解析できません。

データをエスケープしたい場合は、各パラメーターを個別にバインドする必要があります。

ただし、バインドされたパラメーターはデータに対してのみ機能します。列名については、@Michael のコメントで指摘されているように、ホワイトリストを適用する必要があります。列/テーブル名を自動的にエスケープする方法はありません。

これは、PDO を含むすべてのデータベース層に適用されます。レイヤーに完全なクエリ文字列を入力すると、その中のデータは魔法のようにエスケープされません。

于 2013-01-07T12:29:39.863 に答える
0

まあ、これは用語の問題です。ほら、あるよ

  • クエリでデータを表すプレースホルダーの一般的な概念
  • プレースホルダーのサブセットである準備済みステートメント
  • 準備されたステートメントに属する拘束力のあるものですが、省略できます

ほとんどの場合、「バインディング」の下では、準備されたステートメントを意味します。この場合、答えは異なる場合があります。
しかし、プレースホルダーの考え方を採用すると、答えが変わります
。もちろん、クエリを実行する方法は安全ではありません。
ただし、(手動の) バインドなしで完全に安全なクエリを作成することは可能です。
したがって、bind_param は必要ありません。

于 2013-01-07T12:46:55.763 に答える