从SQL注入安全$ _SESSION吗? [英] Is $_SESSION safe from sql injects?

查看:177
本文介绍了从SQL注入安全$ _SESSION吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用PDO访问我的MySQL数据库,并想使用IN.但是可悲的是,它不能与prepare一起使用,所以我写了这个函数

I use PDO to access my MySQL database, and want to use IN. But sadly it don't seam to work with prepare, so I wrote this function

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注入.

I know it, looks ugly. But I don't want any SQL injects.

推荐答案

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

You don't really have to test for the input being numeric, because in MySQL, any string e.g. '123abc' in a numeric context (like being compared to an integer column id) implicitly takes only the digits and ignores the rest. A non-numeric string like 'abc' simply has the integer value 0 because there are no leading digits.

要点是,如果使用查询参数,则从SQL注入中获取值是安全的.输入是来自$ _SESSION还是来自其他来源都是无关紧要的.就SQL注入而言,$ _SESSION既不安全也不不安全,这是将数据传递到查询的重要方式.

The point is, values are safe from SQL injection if you use query parameters. Whether the inputs come from $_SESSION or another source is irrelevant. $_SESSION is neither safe or unsafe with respect to SQL injection, it's how you pass the data to your query that matters.

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

I would also simplify the code to format the list of parameter placeholders:

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

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

And forget about bindParam(), just pass the array to execute().

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


发表您的评论


Re your comment:

在PDO中,您可以使用诸如:id之类的命名参数,也可以使用始终为?的位置参数(但不要在给定查询中混合使用这两种类型,而要使用一种或另一种)

In PDO, you can use either named parameters like :id, or you can use positional parameters, which are always ? (but don't mix these two types in a given query, use one or the other).

将数组传递给execute()会自动将数组元素绑定到参数.一个简单的数组(即用整数索引)很容易绑定到位置参数.

Passing an array to execute() automatically binds the array elements to the parameters. A simple array (i.e. indexed by integers) is easy to bind to positional parameters.

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

If you use named parameters, you must pass an associative array where the keys of the array match the parameter names. The array keys may optionally be prefixed with : but it's not required.

如果您是PDO的新手,那么阅读文档真的很值得.有代码示例,应有尽有!

If you're new to PDO, it really pays to read the documentation. There are code examples and everything!

这篇关于从SQL注入安全$ _SESSION吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆