Is $_SESSION safe from sql injects?

主宰稳场 提交于 2019-12-24 12:48:23

问题


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

Then used it like this

    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();

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


回答1:


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.

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']), '?'));

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:

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

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.

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




回答2:


$_SESSION is just a way to store data on server over a session. It's not direct related with SQL injection.




回答3:


Even if it's a cookie or a session , the hash that I store is alphanumeric only, for security purposes. When I'm checking the cookie/session against any type of inject / modification , I use ctype_alnum:

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

This way, no matter who is setting the SESSION value (you or the client, if you give him the possibility to), there wont be any case in which non-alphanumeric chars like comma, quotes, double quotes or whatever will be inserted.



来源:https://stackoverflow.com/questions/23941182/is-session-safe-from-sql-injects

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!