【问题标题】:Is mysqli_real_escape_string safe?mysqli_real_escape_string 安全吗?
【发布时间】:2014-03-10 15:51:25
【问题描述】:

我是 PHP 新手,我意识到我的数据库连接,使用 php 表单(带有用户和传递文本输入)是完全不安全的:

这是可行的,但不安全:

<?php
$link=mysqli_connect('localhost','xx','xx','xx');
$sql='  SELECT * FROM usuarios 
        WHERE username="'.$_POST['usuario'].'" 
        AND pass="'.$_POST['usuario'].'"
     ';
$rs=mysqli_query($link,$sql);
mysqli_close($link);
?>

所以,我已经阅读了 mysqli_real_escape_string,并决定尝试一下:

<?php    
$link=mysqli_connect('localhost','xx','xx','xx');
$usuario=mysqli_real_escape_string($link, $_POST["usuario"]);
$clave=mysqli_real_escape_string($link, $_POST["clave"]);
$sql='  SELECT * FROM usuarios 
        WHERE username="'.$usuario.'" 
        AND pass="'.$clave.'"
     ';
$rs=mysqli_query($link,$sql);
mysqli_close($link);
?>

这是正确的吗?这是如何使用 mysqli_real_escape_string 的一个很好的例子吗?

【问题讨论】:

  • 如果您使用的是 mysqli,那么您不应该自己转义值。使用占位符,让数据库为您完成所有工作。但除此之外,是的,您正在“正确”使用它,因为使用不正确/过时的编码方法可以被认为是“正确的”
  • 准备好的/参数化的查询是要走的路。我不会认为这是正确的。
  • 仅供参考,在没有加密的情况下在数据库中拥有密码与不转义输入一样糟糕。我的意思不是 md5——使用适当的单向加密和盐。
  • 请在mysqli_real_escape_string 之前和生成的字符串之后给我一个例子。因为会造成混淆,所以没有给出例子。

标签: php mysqli sql-injection


【解决方案1】:

这是正确的吗?

是的。

这是如何使用 mysqli_real_escape_string 的一个很好的例子吗?

如果曾经使用过,这个函数必须被封装到一些内部处理中,并且永远不必直接从应用程序代码中调用。必须使用 占位符 来表示查询中的数据:

$sql='SELECT * FROM usuarios WHERE username=? AND pass=?';

然后,在处理占位符标记时,可能应用此函数(如果适用),但不是单独应用,而是沿所有格式规则应用。

【讨论】:

  • 请在mysqli_real_escape_string 之前和生成的字符串之后给我一个例子。因为它会引起混淆,所以没有给出例子。
  • 可以和存储过程一起使用mysqli_real_escape_string吗?例如:$code = mysqli_real_escape_string($link, filter_var($_POST["code"], FILTER_SANITIZE_STRING)); mysqli_query($link, "CALL sp_updatetable('$code')")? - 请注意:code 不是用户输入。
【解决方案2】:

是的,您将立即使用它。

使用 mysqli 的好处是它是面向对象的。 所以你可以这样使用它:

<?php

$mysqli = new mysqli("host", "user", "password", "database");

$usuario = $mysqli->real_escape_string($_POST["usuario"]);
$clave = $mysqli->real_escape_string($_POST["clave"]);

$sql='  SELECT * FROM usuarios 
        WHERE username="'.$usuario.'" 
        AND pass="'.$clave.'"
     ';

$mysqli->query($sql);

$mysqli->close();
?>

或者你可以使用 PDO。

【讨论】:

    【解决方案3】:

    mysqli() 函数的使用只应保留给框架开发人员和其他了解它可能带来的所有安全问题的人。对于其他所有人,有PDO。它与 mysqli() 一样易于使用,而且更安全。

    【讨论】:

    • "它与 mysqli() 一样易于使用,并且安全得多。" - [需要引用]
    • 好吧,我发布的链接解释了为什么 PDO 比 mysqli() 和字符串连接更安全。如果您仍然不相信,this 的讨论来自 2008 年,并且在今天仍然具有相关性。在我看来,对大部分 SQL 攻击的免疫力绝对是“安全得多”。
    • 我以前读过那篇文章,但我看不出它在哪里解释了“PDO 更安全”。
    • 文章不一定要用“更安全”的字眼来暗示。 “即使你只打算使用一次,使用准备好的语句也有助于保护你免受 SQL 注入攻击。”
    • 如果你之前不知道,PDO 并不垄断准备好的语句。
    猜你喜欢
    • 2016-11-10
    • 2016-03-07
    • 2010-10-09
    • 2023-04-05
    • 2012-12-10
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    相关资源
    最近更新 更多