3

たくさんのPHPファイル(本当にたくさん...)があるWebサイトがあり、PostgreSQLクエリのアポストロフィをエスケープしない関数 pg_queryと関数を使用しています。pg_exec

ただし、セキュリティ上の理由と、データベースにアポストロフィを付けて名前を保存する機能のために、データベース入力にエスケープメカニズムを追加したいと思います。考えられる解決策は、すべてのPHPファイルを調べて、を変更しpg_querypg_exec使用するpg_query_paramsことですが、時間がかかり、エラーが発生しやすくなります。pg_queryPHPファイルを変更せずにエスケープを実行するラッパー関数とラッパー関数をなんらかの方法でオーバーライドすることをお勧めしpg_execますが、この場合、PHP関数定義を変更して再コンパイルする必要があると思いますが、これはあまり理想的ではありません。

ですから、質問はオープンであり、最小限の時間で私がやりたいことを実行できるようなアイデアは大歓迎です。

4

2 に答える 2

3

あなたはコードを投稿しませんが、私はあなたがこれを持っていると思います:

$name = "O'Brian";
$result = pg_query($conn, "SELECT id FROM customer WHERE name='{$name}'");

...そしてあなたはこれを持っている必要があるでしょう:

$name = "O'Brian";
$result = pg_query_params($conn, 'SELECT id FROM customer WHERE name=$1', array($name));

...しかし、あなたはそのタスクが不当な時間を消費すると思います。

確かに複雑ですが、どのような選択肢がありますか?オーバーライドすることはできませんがpg_query()、検索して置き換えるのは非常に簡単ですmy_pg_query()。そして今何?カスタム関数には文字列のみが表示されます。

SELECT id FROM customer WHERE name='O'Brian'
SELECT id FROM customer WHERE name='foo' OR '1'='1'

バグのないSQLパーサーを実装できたとしても:

  1. 無効なSQLでは確実に機能しません。
  2. クエリが意図的なSQLインジェクションの結果であるかどうかを判断することはできません。

簡単に、クエリを1つずつ修正してください。時間はかかりますが、思ったほどではないかもしれません。あなたが進歩するにつれて、あなたのアプリはますます良くなるでしょう。

于 2012-12-20T10:45:55.463 に答える
2

これは、データベースレイヤーと関連するAPIが時間の負荷を節約する場合の完璧な例です。良い解決策は、DBクラスをシングルトンとして作成することです。これは、アプリのどこからでもインスタンス化できます。ラッパー関数の単純なセットを使用すると、DBへのすべてのクエリを1つのポイントで実行できるため、動作方法を非常に簡単に変更できます。また、アプリの他の部分に触れることなく、あるDBから別のDBに、またはあるDBベンダーから別のDBベンダーに変更することもできます。

エスケープで発生している問題は、エスケープを不要にするpg_query()のような関数の代わりに、 PDOインターフェイスを使用することで適切に解決されます。DBを使用するアプリのあらゆる場所を変更する必要があるため、同じ量の作業になると同時に、このパターンを使用するようにリファクタリングすることもできます。

class db_wrapper {

    // Singleton stuff
    private $instance;

    private function __construct() {
        // Connect to DB and store connection somewhere
    }

    public static function get_db() {
        if (isset($instance)) {
            return $instance;
        }
        return $instance = new db_wrapper();
    }

    // Public API

    public function query($sql, array $vars) {
        // Use PDO to connect to database and execute query
    }

}

// Other parts of your app look like this:

function do_something() {
    $db = db_wrapper::get_db();
    $sql = "SELECT * FROM table1 WHERE column = :name";
    $params = array('name' => 'valuename');
    $result = $db->query($sql, $params);

    // Use $result for something. 
}
于 2012-12-20T10:39:45.823 に答える