PHP安全性,intval和htmlspecialchars

时间:2009-08-01 17:28:13

标签: php mysql security

<?php

$id = intval($_GET['id']);

 $sql = mysql_query("SELECT username FROM users WHERE id = $id");
 $row = mysql_fetch_assoc($sql);

$user = htmlspecialchars($row['username']);

?>

<h1>User:<?php echo $user ?></h1>

您能否在上述代码中看到任何威胁?我必须在输出的所有内容上使用htmlspecialchars吗?我应该使用is_numeric或intval来检查get是否为数字?

我只是建立一个最小的网站。我只是想知道上面的代码是否容易受到sql注入,xss?

3 个答案:

答案 0 :(得分:8)

一般来说,mysql_real_escape_string()是首选,但由于它是一个数字,intval()是可以的。所以是的,从安全角度看它看起来不错。

但有一点,在许多平台上,整数限制为32位,所以如果你想要处理大于21亿的数字,那么它将无法工作。好吧,无论如何,它都无法发挥作用。

这些安全预防措施适用于任何形式的用户输入,包括cookie(很多人都忘记了)。

答案 1 :(得分:5)

我强烈建议使用PDO和准备好的声明。虽然您上面的陈述看起来很安全,但只要您执行更复杂的查询,就会遇到问题。

不要担心特定查询是否安全,而是要了解准备好的语句,您不必担心。这是你的例子,用PDO重写:

# Make a database connection
$db = new PDO('mysql:dbname=your_db;host=your_db_server', 'username',
    'password');

# The placeholder (:id) will be replaced with the actual value
$sql = 'SELECT username FROM users WHERE id=:id';

# Prepare the statement
$stmt = $db->prepare($sql);

# Now replace the placeholder (:id) with the actual value. This
# is called "binding" the value. Note that you don't have to
# convert it or escape it when you do it this way.
$stmt->bindValue(':id', $id);

# Run the query
$stmt->execute();

# Get the results
$row = $stmt->fetch();

# Clean up
$stmt->closeCursor();

# Do your stuff
$user = htmlspecialchars($row['username']);

我添加了很多评论;它的代码不像它看起来那么多。当您使用bindValue时,您永远不必担心SQL注入。

答案 2 :(得分:0)

那么,

您正在将收到的ID转换为int;所以这里没有可能的SQL注入。
其余的DB查询都是“硬编码的”,所以也没问题。

如果ID是数据库中的字符串,则必须使用mysql_real_escape_string,但对于整数,intval是正确的工具: - )


关于输出,您也在逃避数据(并且,当您输出HTML时,htmlspecialchars正常);所以没有HTML / JS注入。

所以,这段代码对我来说很合适: - )


作为旁注,如果您正在开始开发新网站,那么现在或者永远不要看看mysqli(而不是mysql)和/或PDO; - )

它允许您使用最近版本的MySQL提供的功能,例如prepared statements - 这是保护自己免受SQL注入的好方法!