防止sql注入的最佳实践是什么
我做了一些研究,但仍然很困惑,这是我的研究结果。有人可以评论并建议我如何使这些变得更好,或者是否已经有一个我可以使用的坚如磐石的实现?
方法一:
array_map('trim', $_GET);
array_map('stripslashes', $_GET);
array_map('mysql_real_escape_string', $_GET);
方法二:
function filter($data) {
$data = trim(htmlentities(strip_tags($data)));
if (get_magic_quotes_gpc())
$data = stripslashes($data);
$data = mysql_real_escape_string($data);
return $data;
}
foreach($_GET as $key => $value) {
$data[$key] = filter($value);
}
I have done some research and still confused, This is my outcome of that research. Can someone please comment and advise to how I can make these better or if there is a rock solid implementation already out there I can use?
Method 1:
array_map('trim', $_GET);
array_map('stripslashes', $_GET);
array_map('mysql_real_escape_string', $_GET);
Method 2:
function filter($data) {
$data = trim(htmlentities(strip_tags($data)));
if (get_magic_quotes_gpc())
$data = stripslashes($data);
$data = mysql_real_escape_string($data);
return $data;
}
foreach($_GET as $key => $value) {
$data[$key] = filter($value);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您展示的两种方法都不推荐,
一揽子“清理”数据会适得其反,因为数据需要根据数据的使用方式以不同的方式进行清理:在数据库查询中使用它与在 HTML 中输出它需要不同的清理,或者将其用作命令行调用中的参数等。
进行清理的最佳方法是在使用数据之前立即进行。这样,程序员就可以轻松查看所有数据是否真正得到了清理。
如果您使用
mysql_*
系列函数,请对查询中使用的每个参数执行mysql_real_escape_string()
:如果您使用 PDO 或 mysqli 函数系列,您可以使用参数化查询,这消除了大多数 SQL 注入问题 - 无论如何都是日常问题。
完全有可能使用 mysql_* 编写安全查询,也完全有可能在 PDO 查询中引入安全漏洞,但如果您是从头开始,请考虑立即使用 PDO 或 mysqli 。
仅当您计划以 HTML 形式输出用户输入的数据时才使用
strip_tags()
;请注意,您需要执行额外的htmlspecialchars()
才能可靠地防止 XSS 攻击。唯一具有一定优点的一揽子卫生方法是
过滤掉由早期版本的 PHP 现已弃用的“魔术引号”功能添加的转义层的调用。
Both methods you show are not recommendable
Blanket "sanitizing" data is counter-productive, because data needs to be sanitised in different ways depending on how it is going to be used: Using it in a database query needs different sanitation from outputting it in HTML, or from using it as parameters in a command line call, etc. etc.
The best way to do sanitation is immediately before the data is being used. That way, it is easy for the programmer to see whether all data is actually getting sanitized.
If you use the
mysql_*
family of functions, do amysql_real_escape_string()
on every argument you use in a query:If you use the PDO or mysqli families of functions, you can make use of parametrized queries, which eliminate most of the SQL injection woes - all everyday ones at any rate.
It is perfectly possible to write safe queries with
mysql_*
, and it is also perfectly possible to introduce a security hole in a PDO query, but if you are starting from scratch, consider using PDO or mysqli straight away.Use
strip_tags()
only if you are planning to output user entered data in HTML; note that you need to do an additionalhtmlspecialchars()
to reliably prevent XSS attacks.The only blanket sanitation method that has some merit is the
call which filters out the layer of escaping added by the now-deprecated "magic quotes" feature of earlier versions of PHP.
我认为这已经足够了(编辑:对于 $data,我们在这里指的是例如表单中的一个文本字段,
$_POST['example']
等):我通常在收到 $_POST 或$_GET 数据(在输入测试之前)以及后者在 sql 查询编写之前或期间。
如果你愿意的话,可以额外修剪它(也许你并不总是想要那样)。然而,最好的解决方案是使用一些库来处理数据库。
I think this is enough (EDIT: with $data we mean here e.g. one text field from a form,
$_POST['example']
etc):I usually do the first when receiving the $_POST or $_GET data (before input testing) and the latter right before - or during - composing of the sql query.
Additionaly trim it, if you want (maybe you don't always want that). However the best solution would be using some libraries for working with database.
您可以:
请注意,如果可能,您应该关闭 magic_quotes。如果它已打开,则只需使用 stripslashes (如您的示例中所示),因为它已被弃用,您不应该依赖它。
另请注意,您不应该对不应插入数据库的数据执行此操作,因为它完全无用。
You can either:
Note that you should turn off magic_quotes if possible. If it's on, just use stripslashes (like in your example) as it's deprecated and you should not rely on it.
Also note that you should not do this for data which is not supposed to be inserted into the database as it's completely useless.
每当你处理 int 时,我都喜欢类型转换;
例如
I like type-casting whenever you're dealing with
int
s;e.g.
好吧,在您的代码中,只有 mysql_real_escape_string() 函数与 SQL 注入相关。然而,完全错位了。
但这还不够。
事实上,这个函数应该只与带引号的字符串一起使用。
而且对其他一切都没用。因此,在任何其他情况下都应采取其他预防措施。
有关完整的解释,请参阅我之前的回答:在 PHP 中,当向数据库提交字符串时,我应该使用 htmlspecialchars() 处理非法字符还是使用正则表达式?
您使用的所有其他函数都没有关系完全转向 SQL。
请注意,同时使用 strip_tags 和 htmlentities 是多余的。并且 htmlentities 已过时。
我只使用
htmlspecialchars()
而不是这两个,并且不是在插入数据库之前,而是在将其发送到浏览器之前。Well, among your codes only mysql_real_escape_string() function is SQL injection related. However, being completely misplaced.
And it's not enough.
In fact, this function should be used with quoted strings only.
And it's useless for the everything else. So, in any other case other precautions should be taken.
For the complete explanation see my earlier answer: In PHP when submitting strings to the database should I take care of illegal characters using htmlspecialchars() or use a regular expression?
All other functions you're using have no relation to SQL at all.
Note that using both strip_tags and htmlentities is redundant. and htmlentities is obsolete.
I'd use only
htmlspecialchars()
instead of these two, and not before inserting into database but right before sending it to browser.