sql注入是否安全$ _SESSION?

时间:2014-05-29 19:13:03

标签: php mysql pdo

我使用PDO访问我的MySQL数据库,并希望使用IN。但遗憾的是,它没有与prepare一起工作,所以我写了这个函数

function is_numeric_array($array){
    if(!is_array($array))
        return is_numeric($array);

    if(is_array($array))
        foreach($array as $int)
            if(!is_numeric($int))
                return false;
    return true;
}

然后像这样使用它

    if(!is_numeric_array($_SESSION['story'])){
        die("Error, array contains non-integers");
    }

    $query = "(";
    for($i = 0; $i<count($_SESSION['story']); $i++)
        $query .= $_SESSION['story'][$i].(count($_SESSION['story'])-1 != $i ? "," : "");
    $query .= ")";

    //Collect all data needed
    $stories = openConnection() -> query("SELECT * FROM `stories` WHERE `id` IN {$query}") -> fetchAll();

我知道,看起来很难看。但我不希望任何SQL注入。

3 个答案:

答案 0 :(得分:4)

你真的不必测试输入是数字的,因为在MySQL中,任何字符串,例如数值上下文中的'123abc'(比如与整数列id进行比较)隐式地仅采用数字而忽略其余数字。像'abc'这样的非数字字符串只有整数值0,因为没有前导数字。

关键是,如果使用查询参数,则SQL注入的值是安全的。输入来自$ _SESSION还是其他来源无关紧要。对于SQL注入,$ _SESSION既不安全也不安全,而是将数据传递给重要的查询。

我还会简化代码以格式化参数占位符列表:

$placeholders = implode(',', array_fill(1, count((array)$_SESSION['story']), '?'));

忘记bindParam(),只需将数组传递给execute()

//Collect all data needed
$storyQuery = openConnection() -> prepare("SELECT * FROM `stories` 
    WHERE `id` IN ({$placeholders})");
$storyQuery -> execute((array)$_SESSION['story']);
$story = $storyQuery -> fetchAll();

重新评论:

在PDO中,您可以使用:id之类的命名参数,也可以使用位置参数,这些参数始终为?(但不要在给定查询中混合这两种类型,请使用一个或者其他)。

将数组传递给execute()会自动将数组元素绑定到参数。简单数组(即由整数索引)易于绑定到位置参数。

如果使用命名参数,则必须传递一个关联数组,其中数组的键与参数名称匹配。

如果您是PDO新手,阅读documentation真的很有意义。有代码示例和一切!

答案 1 :(得分:1)

$ _ SESSION只是一种通过会话在服务器上存储数据的方法。它与SQL注入没有直接关系。

答案 2 :(得分:-2)

出于安全考虑,即使它是cookie或会话,我存储的哈希只是字母数字。当我针对任何类型的注入/修改检查cookie /会话时,我使用ctype_alnum

if (ctype_alnum($_SESSION['value']))
    // exec code
else 
   // trigger_error

这样,无论是谁设置SESSION值(你或客户端,如果你给他的可能性),就不会出现像comma这样的非字母数字字符,{{1 }},quotes或其他任何内容。