我知道我应该使用预备语句,但我的下一个项目将使用预备语句我只需要完成这个简单的小应用程序。
所以我的问题是:
以下代码片段是否安全?
我使用了htmlentities以及mysql_real_escape_string因为我认为这是一个安全的选择。
//Image
$imageInput = $_POST['Image'];
$imageClean = htmlentities($imageInput, ENT_QUOTES, 'UTF-8');
//Inserts values into relevant field and creates a new row.
mysql_query("UPDATE ***** SET image='" . mysql_real_escape_string($imageClean) . "' WHERE id=" . mysql_real_escape_string($idClean) . "");
添加$ idClean的代码是:
//Id to change
if(ctype_digit($_POST['testimonial']))
{
$idInput = $_POST['testmonial'];
$idClean = htmlentities($idInput, ENT_QUTOES, 'UTF-8');
}
感谢您的帮助。
p.s如果你可以建议添加一些很棒的东西。
答案 0 :(得分:4)
取决于$idClean
的清洁程度。
WHERE id=" . mysql_real_escape_string($idClean) . "
mysql_real_escape_string
only prepends backslashes to \x00
, \n
, \r
, \
, '
, "
and \x1a
,但不会阻止攻击者使用
$idClean = "1 OR 1=1 AND POSSIBLY OTHER SQL STATEMENTS"
您应该将其转换为int,而不是mysql_real_escape_string
。
答案 1 :(得分:3)
您应该只在输出点应用实体转义 - 在数据库插入之前转义数据没有任何价值。也就是说,你在mysql_real_escape_string方面正在做正确的事。
除此之外,正如@Piskvor所说,idClean变量存在潜在问题。 (例如,这会被转换为int吗?)
您可以使用以下示例:
mysql_real_escape_string(intval($idClean))
答案 2 :(得分:2)
$ idClean来自哪里?
另一个$ _POST?它应该是一个整数,不是吗?
不要对它进行html清理,只需$idClean = (int)$_POST['id'];
...将'强制'它为整数,'杀死'所有可能的xss / sql注入(仅限$ idCelan我的意思)
总的来说,没有一种最好的方法来消毒输入;所有这些都取决于输入应包含的内容,存储以及将来如何使用。
编辑:在你对middaparka的回答发表评论后,我认为$ idClean来自一个表单(可能是一个隐藏的输入)。
如果你想阻止甚至学习使用那个表格,我建议你用$ idclean哈希添加另一个隐藏字段,然后在进程页面检查哈希,看看是否有人手动更改了id(如果你不会这样做)
这通常是用户管理中的错误设计,不知道你的行为是否正确。
答案 3 :(得分:1)
假设$ _POST ['Image']是一个URI,没有。有人可以使用javascript:scheme提交URI,并让其他人运行任意JavaScript。
答案 4 :(得分:0)
“图片”和ID的预期字符范围是多少?转义输入是一个好主意,您应该始终检查输入是否只包含给定数据类型的合法字符。 e.g。
if (preg_match("/\w(\w|\\.){0,31}/", $imageInput) && preg_match("/\d{1,12}/", $idClean)) {
// do database update
} else {
// invalid input, let the user know!
}
$ imageInput上面的正则表达式应该只允许带有字母数字,下划线和句号的图像名称。长度为1到32个字符(您可能希望将其与数据库定义相匹配)。不允许其他角色。我做了记忆中的正则表达式,请原谅我,如果逃避不正确,但使用正则表达式对已知良好输入进行消毒的原则是可行的。
数据库安全不是您需要考虑的安全性的唯一方面。考虑跨站点脚本(XSS)。如果用户输入图像名称,请执行以下操作:javascript:alert('abc');然后当你将它显示给用户时,它将在他们的浏览器中执行!
答案 5 :(得分:0)
正如您在id=xyz
遇到问题之前所说的那样。但是,不是将它转换为php中的整数,而是将其作为字符串文字传递,原因有两个:
id
并不总是必须是整数。connection charset会影响mysql_real \ escape_string()的行为。因此,您应该将连接资源作为第二个参数传递给mysql_real \ escape_string()。
在插入数据之前是否使用htmlentities()取决于您想要实现的目标。如果您需要将数据作为html / utf-8之外的其他内容,则必须将其转换回来。但是因为这与安全无关......按照自己的方式行事; - )
$mysql = mysql_connect('..', '..', '..');
//...
$query = sprintf("
UPDATE
*****
SET
image='%s'
WHERE
id='%s'
",
mysql_real_escape_string($imageClean, $mysql),
mysql_real_escape_string($id, $mysql)
);
哦,顺便说一句:强制性暗示准备好的陈述:http://docs.php.net/pdo.prepared-statements