从SQL注入安全$ _SESSION吗? [英] Is $_SESSION safe from sql injects?
问题描述
我使用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屋!