我读过这个:
将帮助您免受注射。 因为逃避只是一个字符串格式化设施,而不是任何方式的防喷射。 去搞清楚。 但是,转义与准备好的语句有一些共同之处: 他们都不保证你注射 你只使用它来对抗臭名昭着的“用户输入”,而不是建立任何查询的严格规则,尽管有数据源。 如果您需要插入不是数据而是标识符或关键字。
在以下帖子中:Are dynamic mysql queries with sql escaping just as secure as prepared statements?
所以我的问题是使用:
$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()
prepared
语句的$GetCompletedQuery = $STD->query("SELECT Status FROM UserCompletion WHERE `UserID`=' ". $STD->real_escape_string($_SESSION['UID']) ."'");
$GetCompletedArray = $GetCompletedQuery->fetch_array(MYSQLI_ASSOC);
equlivant,它将提供完整的SQL注入预防,因为准备好的语句将数据作为原始数据发送。
此格式的第一个问题如下:
我使用的查询为:
$GetCompletedQuery = $STD->prepare("SELECT Status FROM UserCompletion WHERE `UserID`=?");
$GetCompletedQuery->bind_param('i', $_SESSION['UID']);
$GetCompletedQuery->execute();
$GetCompletedArray = $GetCompletedQuery->fetch_row;
print_r($GetCompletedArray);
返回:
数组([状态] => 1)
但是使用准备好的陈述:
fetch_array()
返回:
致命错误:在第17行的/var/www/New/API/Constants.php中调用非对象的成员函数fetch_row()
当我尝试$GetCompletedQuery = $STD->query("SELECT Status FROM UserCompletion WHERE `UserID`=' ". $STD->real_escape_string($_SESSION['UID']) ."'");
时会出现同样的情况,我知道这些fetch_array();
不能用于准备好的语句。
那么使用预准备语句的选项是什么?
第二个问题
如果我使用我的常用查询:
$_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'];
是从SQL注入中正确保护的数据吗?
第三个问题:
我是否应该逃避/保护$_SESSION['real_name'];
的SQL注入,因为这是在以下庄园中分配的:
$_SESSION['UID'];
此片段解释了:
用户使用用户名&进行登录密码,该文件根据$_SESSION['real_name'];
从数据库中获取信息
并添加带有结果的$ _SESSION数组,将每个数组添加到不同的键中。
这个块的问题是,当基于{{1}}
通过数据库分配{{1}}时,我甚至应该逃避/防止SQL注入谢谢你抽出时间阅读这个庞大的大块。
答案 0 :(得分:5)
是否使用
$mysqli->real_escape_string($Var);
不能提供针对SQL注入的保护?
我没有改变主意:肯定,但事实并非如此。
只有将结果值括在引号中(并使用mysqli_set_charset()
设置正确的编码才是严格的),它才会这样做。
看,SQL注入不是必需的东西,它本身就存在,但它仅仅是一种后果。查询格式不正确的结果 创建查询时,必须正确格式化它的每个部分。不是因为“注射”,而是为了它。当您要在查询中插入字符串时,您必须将其放入引号,否则您将收到语法错误。当您要在查询中插入字符串时,您必须转义这些引号用于分隔此字符串,否则您将收到语法错误。等等。适当的格式应该是你关注的问题,而不是关于注射的恐慌。并且只要您根据其类型正确格式化每个动态查询部分 - 无法进行注入
因此,变量的来源或它的价值永远不应该是您的关注点。但只有它位于查询中:
如果是查询的 static 部分,在脚本中硬编码,我们不会使用这样严格的标准 - 比方说,我们不会将每个标识符都包含在反引号中。
但是当它用于查询的动态部分时,应用格式规则应该是严格的规则,因为我们无法确定变量内容。
顺便说一句,还有另一种格式化字符串和数字的方法 - 准备好的语句。它不是那么方便,但是因为它使用占位符来表示查询中的数据,所以建议使用过于愚蠢的手动格式化。