题
这段 php 代码有多危险?对此我们能做些什么呢?
$name = $_POST["user"];
$pwd = $_POST["pwd"];
$query = "SELECT name,pwd FROM users WHERE name = '$name' AND pwd = '$pwd'";
解决方案
可能出现的问题:
- SQL注入
- XSS注入(如果此代码是插入查询,那将是一个明确的问题)
- 纯文本密码 醇>
您的SQL语句可能会有问题。让自己打开SQL注入是不好的做法。
SQL注入错误。相信我。
如果你想在HTML页面上显示$ user,那么你可能不想让人们能够<!>“hack <!>”;通过输入
等命令来进行布局<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)))
其他提示
这很危险:
除了SQL注入之外,看起来您的密码可能以纯文本形式存储,这不是很好。
如果您从未将$ query传递给SQL数据库,那么该代码非常安全。
如果要发布0';drop table users;--
名称
你的命令最终将成为
select name, pwd form users where name='0';
drop table users; --'and pwd = '[VALUE OF PWD]'
首先,它会获取您的数据,然后杀死您的用户表,并且对其余部分不执行任何操作,因为它是评论。
php中的某些mysql命令会在传递sql时执行多个查询,避免这种情况的最佳方法是参数化查询。
我使用PDO进行所有数据库访问,并强烈推荐它。我没有任何链接,但我记得我使用的教程超过谷歌。
它不仅容易发生SQL注入,而且在注意甚至不打算的情况下也会失败:
例如,用户想要名称<!>“Guillaume Fran <!>#231; ois Antoine,Marquis de L <!>#8217; Hospital <!> quot;。由于用户名包含引号并且您没有转义它,您的查询将失败,尽管用户从不想破坏系统!
使用 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']))
);
信不信由你,这是安全的......如果magic_quotes_gpc
开启了。它永远不会在PHP6中,所以在此之前修复它是一个好主意。
$_POST['user'] = "' or 1=1; --";
任何人都可以立即访问您的应用程序$_POST['user'] = "'; DROP TABLE user; --";
与你的(付费?)用户列表吻别如果您稍后在输出中回显 $name,则可能会导致 XSS 注入攻击
:哦,从来没有做过, 这可能会导致SQLInjection攻击。如果例如用户输入某种方式: 'drop table users - 作为$ username的输入;此代码将与您的原始代码相结合,并将删除您的表。黑客可以做得更多,可以破解你的网站。
这通常非常危险。在某些情况下,它可以通过数据库权限来缓解。
您不验证输入($ name和$ pwd)。用户可以在这些字段中的一个或两个中发送SQL。 SQL可以删除或修改数据库中的其他数据。
非常危险。密码的一个好主意是将密码转换为MD5哈希并将其存储为用户的“密码”。
1)保护用户免于密码被盗
2)如果用户写了恶意字符串,他们可以清除你的条目/表/数据库
此外,你应该在名称上做一些基本的匹配正则表达式,以确保它只使用A-Za-z0-9和一些重音字符(没有特殊字符,*'s,<!> lt;'s ,<!> gt;特别是)。
在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
}
它不安全,你可能想看看像PDO这样的东西。 PHP PDO