php - $_SESSION 对 sql 注入(inject)安全吗?

标签 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 注入(inject)。

最佳答案

您实际上不必测试输入是否为数字,因为在 MySQL 中,任何字符串,例如'123abc' 在数字上下文中(比如与整数列 id 进行比较)隐含地只接受数字并忽略其余部分。像 'abc' 这样的非数字字符串只有整数值 0,因为没有前导数字。

重点是,如果您使用查询参数,则值不会受到 SQL 注入(inject)的影响。输入是来自 $_SESSION 还是其他来源是无关紧要的。对于 SQL 注入(inject),$_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() 会自动将数组元素绑定(bind)到参数。一个简单的数组(即由整数索引)很容易绑定(bind)到位置参数。

如果您使用命名参数,则必须传递一个关联数组,其中数组的键与参数名称匹配。数组键可以选择以 : 为前缀,但这不是必需的。

如果您是 PDO 的新手,阅读 documentation 确实值得.有代码示例和一切!

关于php - $_SESSION 对 sql 注入(inject)安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23941182/

相关文章:

php - PDO 可以在本地连接到 MySQL,但不能连接到远程,即使它们是同一台服务器

php - 有条件地显示 HTML 而不将其包装在 PHP echo 语句中

php - laravel ORM 关系 : left Join like query with optional condition on the right table

php - 未发送 Google YouTube API 刷新 token

mysql - 经典 ASP 在打开 MySQL 时生成 500 错误

mysql - 如何选择年龄范围内的人

php - 如何检查用户是否在 Prestashop 的结帐页面

php - 如何使用if来匹配不同的文本字符串

mysqldump - 如何在内容中获取换行符而不是 LF?

php - PDO 数据库抽象层,在一个请求中具有多个查询