Php 什么时候使用真正的逃逸字符串合适?当数据以POST方式到达时,还是在编写查询之前?
我们知道,为了防止字符串值被转义,必须在组成SQL查询之前进行转义,特别是来自用户或其他外部源的值 这件事什么时候做?是否应在值进入程序时执行此操作,存储转义值以供以后使用?或者应该存储未转义的值,并在编写查询时转义它?哪种方法更安全?折衷是什么 1) 接收到值时转义的示例:Php 什么时候使用真正的逃逸字符串合适?当数据以POST方式到达时,还是在编写查询之前?,php,database,mysqli,escaping,code-injection,Php,Database,Mysqli,Escaping,Code Injection,我们知道,为了防止字符串值被转义,必须在组成SQL查询之前进行转义,特别是来自用户或其他外部源的值 这件事什么时候做?是否应在值进入程序时执行此操作,存储转义值以供以后使用?或者应该存储未转义的值,并在编写查询时转义它?哪种方法更安全?折衷是什么 1) 接收到值时转义的示例: $test = $mysqli->real_escape_string($_POST['test']); . . . $query=" UPDATE * from test_panel where test='
$test = $mysqli->real_escape_string($_POST['test']);
.
.
.
$query=" UPDATE * from test_panel where test='" . $test . "'";
2) 组成查询时转义的示例:
$test = $_POST['test'];
.
.
.
$query=" UPDATE * from test_panel where test='" . $mysqli->real_escape_string('$test') . "'";
这些方法之间有区别吗?哪种方法更容易注射,什么是防止注射的最安全的方法?无论是在查询之前还是在查询中转义输入都无关紧要 是的,一切都必须逃脱。你没有理由不想逃避自己的东西
如果您不想转义字符串,您会意识到;-) 你应该尽可能晚地逃离他们 您希望这样做的原因是,您的数据总是准确的。例如,如果在开头转义字符串,则strlen的
strlen
将与未转义的版本不同,这在某些情况下可能会导致混淆/错误
对于您的问题,真正的(imo)答案是忘记转义,使用首先,您应该将连接作为mysqli real转义字符串中的第二个参数传递 其次,你还应该使用事先准备好的语句
在组成查询时实际使用之前,决不能转义值。无论您是使用准备好的语句/PDO,还是使用real_escape_字符串将查询组合为SQL格式的字符串,这都是正确的 过早清理/转义数据值并将其保存为该格式的做法会导致错误。如果变量包含数据值,如客户名称或帐号,则该变量应包含原始值un转义 只有当您实际形成查询时,才应该确保在将所有值放入该查询时对其进行了正确编码 将保存原始数据值的变量视为与保存查询的变量不同的变量类型。切勿将查询值直接指定给原始数据值,也不得将原始数据值组合起来进行查询。查询的组成是知道应该对原始数据值进行编码的触发器 通过将此作为一种实践,在编码发生的地方将变得清晰和一致,您将减少双重编码或编码失败的可能性 假设您试图做相反的事情:对所有值进行预编码。这实际上是不可能的,因为您有许多字符串值,并且并不是所有的字符串值都要在查询中使用。在某些地方,您可能会有一个变量,该变量既用作显示的输出,也用于查询。显示转义值将不正确。同样很难(或不可能)跟踪哪些变量用于查询,哪些变量用于其他非SQL用途
始终在所有字符串变量中存储原始(未转义)值,直到您实际编写查询为止。这种做法也与使用预处理语句一致,因为预处理语句会传递一个未转义的值 这是一个很有趣的问题,但答案并不那么容易 什么时候使用真正的逃逸字符串合适?当数据以POST方式到达时,还是在编写查询之前 两者都不是 让我解释一下 首先,让我们整理一下术语。这个问题提出的方式有很多错误
$mysqli->real\u escape\u字符串(“$test”)
会使代码臃肿且难以阅读。为什么不让数据库驱动程序为您进行所有格式化?因此,您必须遵循最现代的技术—使用占位符来表示查询中的数据。在处理这样一个占位符时,驱动程序将自动格式化该占位符所在位置的数据。而且既安全又方便。
$db->prepare("SELECT * from test_panel where test=?");
$db->execute(array($_POST['test']));
function paraQuery()
{
global $mysqli;
$args = func_get_args();
$query = array_shift($args);
$query = str_replace("%s","'%s'",$query);
foreach ($args as $key => $val)
{
$args[$key] = $mysqli->real_escape_string($val);
}
$query = vsprintf($query, $args);
$result = $mysqli->query($query);
if (!$result)
{
throw new Exception($mysqli->error()." [$query]");
}
return $result;
}
$query = "SELECT * FROM table where a=%s AND b LIKE %s LIMIT %d";
$result = paraQuery($query, $a, "%$b%", $limit);
$result = paraQuery("SELECT * from test_panel where test=%s", $_POST['test']);