与库MySQLi正确转义| 查询过预处理语句(Properly Escaping with My

2019-07-18 04:29发布

我已阅读本:

将帮助你不反对注射。 Beause逃避只是一个字符串格式化功能,不防注入以任何方式。 去搞清楚。 然而,逃避有一些共同点和预处理语句:他们俩不一样,如果你使用的是它仅针对臭名昭著的“用户输入”,不作为建筑物的任何查询一条严格的规则,尽管数据源从注入你保证。 如果你需要插入不是数据,但标识或关键字。

在下面的帖子: 与SQL溢出就像准备好的语句作为安全动态的MySQL查询?

所以我的问题是,使用:

$Var = "UserInput Data Possible SQL Injection";
$mysqli->real_escape_string($Var);

不提供针对SQL注入防护?

我想用$mysqli->query(); 所以可以使用fetch_array(MYSQLI_ASSOC); 因为坦率地说,我不知道如何使用后,获取结果作为数组prepared的语句。

所以,如果我有这在我的数据库连接:

$STD = new mysqli('localhost', 'root', 'xx', 'xx');
$STD->set_charset('utf8');

if ($STD->connect_error) {
    die("Standard Access Has Been Revoked. Please Contact Administration"); 
}elseif (!$STD){
die ("Other problem With Connecting To Database, Please Contact Administration");
}

如手册中所述的用于real_escape_string

http://php.net/manual/en/mysqli.real-escape-string.php

上述名单:

注意安全:默认字符集的字符集必须设置或者在服务器级别,或使用API函数mysqli_set_charset()为它影响mysqli_real_escape_string()。 参见字符集的概念部分获取更多信息。

哪个环节: http://php.net/manual/en/mysqli.set-charset.php


我的整个问题可以分成三个选项,第一个会被要求一个fetch_array() equlivant的prepared ,由于准备的语句发送数据作为原始报表,这将提供完整的SQL注入预防。


这种格式的第一个问题如下:

我使用的是查询为:

$GetCompletedQuery = $STD->query("SELECT Status FROM UserCompletion WHERE `UserID`=' ". $STD->real_escape_string($_SESSION['UID']) ."'");
$GetCompletedArray = $GetCompletedQuery->fetch_array(MYSQLI_ASSOC);

返回:

阵列([状态] => 1)

但是,使用预处理语句:

$GetCompletedQuery = $STD->prepare("SELECT Status FROM UserCompletion WHERE `UserID`=?");
$GetCompletedQuery->bind_param('i', $_SESSION['UID']);
$GetCompletedQuery->execute();

$GetCompletedArray = $GetCompletedQuery->fetch_row;

print_r($GetCompletedArray);

返回:

致命错误:调用一个成员函数fetch_row()一个非对象在/var/www/New/API/Constants.php第17行

当我尝试同样出现fetch_array()我知道能不能用准备好的语句中使用。

那么,什么将是一个使用准备好的语句的选项?


第二个问题

如果我用我一贯的查询为:

$GetCompletedQuery = $STD->query("SELECT Status FROM UserCompletion WHERE `UserID`=' ". $STD->real_escape_string($_SESSION['UID']) ."'");

这使我使用fetch_array(); 在数据正确地从SQL注入安全吗?


第三个问题:

我应该逃避/从SQL注入保护了$_SESSION['UID']; 因为这被分配在以下庄园:

$InnerJoinQuery = $STD->query("
        SELECT Users.ID, Users.Username, Users.Password, UserInformation.LastName, UserInformation.Firstname, UserInformation.DOB
        FROM Users
        INNER JOIN UserInformation
        ON Users.ID = UserInformation.UserID WHERE Users.Username = '".$_SESSION['real_name']."'");
        $InnerJoinArray = $InnerJoinQuery->fetch_array(MYSQLI_ASSOC);

    $_SESSION['UID'] = $InnerJoinArray['ID'];
    $_SESSION['Password'] = $InnerJoinArray['Password'];
    $_SESSION['Firstname'] = $InnerJoinArray['Firstname'];
    $_SESSION['LastName'] = $InnerJoinArray['LastName'];
    $_SESSION['DOB'] = $InnerJoinArray['DOB'];

这段代码解释:

用户登录用的用户名和密码,将文件从基于数据库中获取信息$_SESSION['real_name']; 并增加了$ _SESSION阵列的结果,加入到每一个不同的密钥。

此块的问题是我应该甚至可以逃脱/从SQL注入保护当$_SESSION['UID']; 通过基于所述数据库中分配$_SESSION['real_name'];

谢谢你们的时间,阅读了这个巨大的块。

Answer 1:

  1. http://php.net/manual/en/mysqli-stmt.get-result.php
  2. 是的,但它是非常不好的做法:
    • 它会帮助你在这种情况下,但只有在这种情况下,与其他任何欺骗
    • 手动逃逸仅仅是愚蠢的,最好让司机为你做它
  3. 是的,因为有像SQL注入,但不正确的格式没有这样的事ONLY

在于,使用$mysqli->real_escape_string($Var); 不提供针对SQL注入防护?

我没有改变我的脑海里: 肯定的是,事实并非如此。
如果你用引号括起来所得到的值(和使用设置正确的编码它只会做mysqli_set_charset()要严格)。

瞧,SQL注入不是必需的,存在于它自己的,但它是相当单纯的结果。 格式不正确的查询的结果。
当创建一个查询时,你必须正确地格式化的每一个部分。 不是因为什么“注入”,但对于它的缘故。 当你要插入一个字符串进入查询时,你必须把它放到引号,否则你会得到一个语法错误。 当你要插入一个字符串到查询,你有逃避这些报价被用于分隔这个字符串,或者你会得到一个语法错误。 等等。 这是正确的格式应该是你的关心,而不是吓唬关于注射故事。 而且只要你按照它的类型正确格式化每个动态查询部分-没有永远注射可能是可能的

因此,可变的来源或它的价值不应该是你的关心。 但是,只有它的位置在查询:

  • 字符串必须用引号括起来,并让这些报价逃脱。
  • 数字必须被转换为它的类型。
  • 标识符已被封闭在反引号和已这些反引号一倍

当它会在查询的静态部分,在脚本中硬编码,我们不使用这种严格的标准-说,我们不是封闭在反引号每个标识符。
但是,当它是怎么回事了查询的动力部分,应用格式规则应该是严格的规定,因为我们不能确切知道变量的内容。

顺便提一下,还有另一种方式来格式化字符串和数字 - 预处理语句。 这是不应该的那样方便,但因为它是使用占位符来表示在查询数据时,则建议使用过愚蠢的手动格式。



文章来源: Properly Escaping with MySQLI | query over prepared statements
标签: php mysqli