在PHP PostgreSQL中转义SQL查询

时间:2012-12-20 10:20:47

标签: php sql database postgresql escaping

我有一个包含大量PHP文件的网站(真的很多......),它们使用的是pg_querypg_exec函数 在Postgre SQL查询中逃避撇号。

但是,出于安全原因和存储名称的能力 我的数据库中的撇号我想为我的数据库输入添加一个转义机制。一个可能的解决方案是去 通过每个PHP文件并更改pg_querypg_exec以使用pg_query_params,但这非常耗时 并且容易出错。一个好主意是以某种方式覆盖pg_querypg_exec到包装函数 在不必更改任何PHP文件的情况下进行转义,但在这种情况下,我想我将不得不更改PHP函数 定义并重新编译它不是很理想。

所以,问题是开放的,任何想法都会 允许以最少的时间消耗我想做的事情非常受欢迎。

2 个答案:

答案 0 :(得分: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注入的产物。
  3. 只需轻松一点,逐一修复查询。这需要时间,但可能没有你想象的那么多。随着您的进步,您的应用会越来越好。

答案 1 :(得分:2)

这是一个完美的例子,说明数据库层和相关API何时可以节省大量时间。一个好的解决方案是将DB类作为单例,您可以从应用程序的任何位置实例化。一组简单的包装函数将允许您对数据库的所有查询都经过一个点,这样您就可以非常轻松地改变它们的工作方式。您也可以从一个数据库更改为另一个数据库,或从一个数据库供应商更改为另一个数据库,而无需触及应用程序的其余部分。

使用PDO接口而不是像pg_query()这样的函数可以正确解决转义问题,这使得转义变得不必要。看到您必须在使用数据库的应用程序中的任何地方进行更改,您也可以同时重构使用此模式,因为它将是相同的工作量。

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. 
}