3

这个 php 代码有多危险?可以做些什么呢?

$name = $_POST["user"];
$pwd = $_POST["pwd"];
$query = "SELECT name,pwd FROM users WHERE name = '$name' AND pwd = '$pwd'";
4

13 回答 13

24

可能的问题:

  1. SQL 注入
  2. XSS 注入(如果此代码是插入查询,那将是一个明确的问题)
  3. 纯文本密码

您的 SQL 语句可能有问题。让自己为 SQL 注入敞开心扉是不好的做法。

SQL 注入很糟糕。相信我。

如果您想在 HTML 页面上显示 $user ,那么您可能不想让人们通过键入以下命令来“破解”您的布局

<H1>HI MOM</H1>

或一堆javascript

此外,永远不要以纯文本形式存储您的密码(很好,抓住 cagcowboy!)。它为管理(或破解)您的数据库的人提供了太多的权力。您永远不需要知道某人的密码。

尝试以下策略:

// mostly pulled from http://snippets.dzone.com/posts/show/2738
function MakeSafe($unsafestring) 
{
    $unsafestring= htmlentities($unsafestring, ENT_QUOTES);

    if (get_magic_quotes_gpc()) 
    { 
        $unsafestring= stripslashes($unsafestring); 
    }

    $unsafestring= mysql_real_escape_string(trim($unsafestring));
    $unsafestring= strip_tags($unsafestring);
    $unsafestring= str_replace("\r\n", "", $unsafestring);

    return $unsafestring;
} 

// Call a function to make sure the variables you are 
// pulling in are not able to inject sql into your 
// sql statement causing massive doom and destruction.

$name = MakeSafe( $_POST["user"] );
$pwd = MakeSafe( $_POST["pwd"] );

// As suggested by cagcowboy: 
// You should NEVER store passwords decrypted.
// Ever.  
// sha1 creates a hash of your password
// pack helps to shrink your hash
// base64_encode turns it into base64
$pwd = base64_encode(pack("H*",sha1($pwd)))
于 2009-03-06T18:55:26.247 回答
14

这很危险: xkcd 鲍比桌

于 2009-03-06T19:35:51.830 回答
12

除了 SQL 注入之外,看起来您的密码可能以纯文本形式存储,这不是很好。

于 2009-03-06T18:55:41.037 回答
12

如果您从不将 $query 传递给 SQL 数据库,那么该代码是非常安全的。

于 2009-03-06T18:57:55.430 回答
3

如果有人要发布0';drop table users;--一个名字

你的命令最终会是

select name, pwd form users where name='0'; 
drop table users; --'and pwd = '[VALUE OF PWD]'

所以首先它会获取你的数据,然后杀死你的用户表,其余的什么都不做,因为它是一个评论。

php 中的某些 mysql 命令在传递 sql 时会执行多个查询,避免这种情况的最佳方法是参数化查询。

我使用 PDO 进行所有数据库访问,并强烈推荐它。我没有任何链接,但我记得我使用的教程超过了谷歌。

于 2009-03-06T19:02:25.997 回答
3

它不仅容易发生 SQL 注入,而且在甚至不打算注入的情况下也会失败:

例如,用户想要名称“Guillaume François Antoine, Marquis de L'Hospital”。由于用户名包含引号并且您没有转义它,因此您的查询将失败,尽管用户从不想破坏系统!

要么使用PDO ,要么以这种方式进行:

$query = sprintf(
                   "SELECT 1 FROM users WHERE name = '%s' AND password = '%s'",
                   mysql_real_escape_string($_POST['name']),
                   mysql_real_escape_string(md5($_POST['password']))
                 );

于 2009-03-06T19:03:23.157 回答
2

信不信由你,这是安全的……如果magic_quotes_gpc打开的话。它永远不会出现在 PHP6 中,因此在此之前修复它是个好主意。

于 2009-03-06T19:27:23.487 回答
1
  1. $_POST['user'] = "' or 1=1; --"; 任何人都可以即时访问您的应用

  2. $_POST['user'] = "'; DROP TABLE user; --"; 吻你的(付费?)用户列表再见

  3. 如果您稍后在输出中回显 $name,则可能导致 XSS 注入攻击

于 2009-03-06T20:20:45.840 回答
0

:O 永远不要这样做,这可能会导致 SQLInjection 攻击。例如,如果用户以某种方式输入: ' drop table users -- as input in $username; 此代码将连接到您的原始代码并删除您的表格。黑客可以做更多事情,并且可以入侵您的网站。

于 2009-03-06T18:55:43.127 回答
0

这通常是非常危险的。在某些情况下,它可以通过数据库权限来缓解。

您不验证输入($name 和 $pwd)。用户可以在其中一个或两个字段中发送 SQL。SQL 可以删除或修改数据库中的其他数据。

于 2009-03-06T18:56:48.350 回答
0

非常非常危险。密码的一个好主意是将密码转换为 MD5 哈希并将其存储为用户的“密码”。
1) 保护用户免于密码被盗 2) 如果用户写入恶意字符串,他们可能会清除您的条目/表/数据库

此外,您应该对名称做一些基本的匹配正则表达式,以确保它只使用 A-Za-z0-9 和一些重音字符(特别是没有特殊字符,*'s,<'s,>'s) .

于 2009-03-06T18:58:53.040 回答
0

它不安全,您可能想研究 PDO 之类的东西。 PHP PDO

于 2009-03-06T18:59:57.517 回答
0

当 SQL 查询中涉及用户数据时,始终使用mysql_real_escape_string.

此外,您应该只存储密码的加盐哈希而不是密码本身。您可以使用以下函数生成并检查具有随机盐值的盐化哈希:

function saltedHash($data, $hash=null)
{
    if (is_null($hash)) {
        $salt = substr(md5(uniqid(rand())), 0, 8);
    } else {
        $salt = substr($hash, 0, 8);
    }
    $h = $salt.md5($salt.$data);
    if (!is_null($hash)) {
        return $h === $hash;
    }
    return $h;
}

全部一起:

$query = 'SELECT pwd FROM users WHERE name = "'.mysql_real_escape_string($_POST['user']).'"';
$res = mysql_query($query);
if (mysql_num_rows($res)) {
   $row = mysql_fetch_assoc($res);
   if (saltedHash($_POST["pwd"], $row['pwd'])) {
       // authentic
   } else {
       // incorrect password
   }
} else {
   // incorrect username
}
于 2009-03-06T19:35:02.533 回答