【问题标题】:MYSQL is not secure but why [duplicate]MYSQL 不安全,但为什么 [重复]
【发布时间】:2015-12-08 07:28:27
【问题描述】:

我有一个我在 MYSQL 和 PHP 中创建的应用程序,据说 MYSQL 会受到 SQL 注入的影响——(我尊重这一点)但为什么呢?我的代码在这种情况下可以正常工作,或者有人可以证明我错了吗?

有一个包含 2 个字段、用户名和密码的表单,我将其发布在一个页面上。这是我的代码:

$user = stripslashes($user);
$pwd = trim($pwd);
$pwd = stripslashes($pwd);
$user = mysql_real_escape_string($user);
$pwd = mysql_real_escape_string($pwd);
$pwd = md5($pwd);

$rs = mysql_query("select * from `login` where upper(USER_ID) = upper('$user') AND PASS = '$pwd'");

我的用户名是管理员。

那么,那是我的代码,我在做转义,这怎么可能受到 SQL 注入?对于那些说 PDO 是未来的人来说,这是一个公开的挑战 :)。

谢谢。

【问题讨论】:

  • 是时候跨入 21 世纪了。 MD5 也经历了更好的日子。
  • mysql_real_escape_string 有很多方法。不过,它们通常涉及奇怪的 Unicode 字符。 md5 不安全,很确定制作它的人已经这么说了。
  • 你真的不应该使用 MD5 密码哈希,你真的应该使用 PHP 的 built-in functions 来处理密码安全。如果您使用的 PHP 版本低于 5.5,您可以使用 password_hash() compatibility pack
  • 你可能仍然可以使用 mysql_ 函数,但 MD5 最终会咬你,比垃圾场的狗还难。
  • 为什么? mysql_ API 有巨大的安全漏洞,一些功能,如mysql_real_escape_string() 很容易被击败。一旦被击败,您可能会被介绍给Little Bobby Tables。此外,针对 MD5 的 hack 被广泛宣传,使得哈希非常容易被破解。

标签: php mysql mysqli pdo sql-injection


【解决方案1】:
$user = stripslashes($user);

只要你先使用addslashes就可以了。

$pwd = trim($pwd);

我不喜欢这样,因为您正在默默地从我选择的密码中删除字符。如果我的密码是:" liIo1sor&DINg "怎么办?

mysql_real_escape_string(x)

这样做的问题是您拒绝了一个替代方案,该替代方案基本上可以确保您容易受到 SQLi 与转义的攻击,这有可能会出现一些随机漏洞并破坏您的网站。

发件人:http://php.net/manual/en/pdo.prepared-statements.php

如果应用程序专门使用预准备语句,开发人员可以确保不会发生 SQL 注入(但是,如果查询的其他部分是使用非转义输入构建的,则仍然可能发生 SQL 注入)。

这是来自官方 PHP 文档。你的方法可能是安全的,但是你有一个非常完美的方法可用......那为什么要选择可能安全的呢?

所以让我们假设mysql_real_escape_string() 是完美的并且会普遍防止注入。您仍然有一个问题,如果您按照本文中的方式构建所有 SQL 查询,那么您(或其他开发人员)可能会出现并添加一个参数并忘记转义它强>。这不是一个安全的起点,并鼓励冒险的发展。

md5($pwd);

正如其他人所说,不应将 md5 用于散列密码。如果可以,您可能应该使用 bcrypt、scrypt 或 pbkdf2。您还省略了每个用户唯一和随机的盐。如果您打算不使用准备好的语句,这一点尤其重要,因为您的数据库将不可避免地被盗(开个玩笑:P)。更多关于在此处存储密码的信息:https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords

【讨论】:

  • 我想我知道你在答案中提到的任何内容,因为我也在我的大学学习过,但正如我所说的例子值得一千个逻辑,即使我的代码在 mysql 中,它也不是易受攻击的:)
  • 如果您不想要建议,为什么要问问题?漏洞是当您维护并忘记转义参数时。
  • 尊敬的建议是由一些逻辑和推理特别证明提供支持
  • 我不确定我是否理解你想用该评论说什么,但似乎回答这个问题的唯一方法是说“你完全正确”或证明 0 -day反对函数?
【解决方案2】:
$user = stripslashes($user);
$pwd = stripslashes($pwd);
$user = mysql_real_escape_string($user);
$pwd = mysql_real_escape_string($pwd);
$password = password_hash($password, PASSWORD_BCRYPT);c
$rs = mysql_query("select * from `login` where upper(USER_ID) = upper('$user') AND PASS = '$pwd'");

这是一种安全的方法,登录时的快速说明,您必须再次在字符串上使用mysql_real_escape_stringmysql_query,然后在这两个函数的输出上运行password_verify()。此外,您可以使用trim,但您也必须在登录时使用。这可能会缩短用户密码并使他们更容易被暴力破解,所以我不推荐它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 2019-10-27
    • 1970-01-01
    • 2014-04-30
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多