PHP 对于字符串在存入数据库之前,以及取出来之后,到底应该做哪一些过滤和转义?

2014-12-13 19:11:24 +08:00
 abelyao
突然想到一个比较初级的问题,但如果要做到完善,我相信这也不是一件容易的事。

问题是这样的,PHP 在接收到客户端 POST 过来的数据之后,尤其是 “自由型” 的文本,例如论坛发帖、商品描述等等,在存入数据库之前,以及从数据库取出之后,要 echo 到页面上,都需要做哪一些过滤和转义,并且保持用户提交的,和下次用户在页面上看到的是一致的内容。这一些过滤和转义,PHP 自带的函数是否可靠?

这问题又涉及到两个分支:第一个是技术型论坛的帖子内容,当用户发帖的内容中包含 html 代码的话,在页面上也需要原封不动的显示出来;第二个是商品描述类型的,其实就是一定范围的富文本,可以改变字号什么的,这些代码是有起到作用的,而不是直接显示。

可能这问题对于经验丰富的开发者来说是比较初级的,也是必修课,但我还是希望能集思广益,大家一起来讨论,用哪些函数、执行的顺序、哪一些常见的函数有什么已知的漏洞,等等,或许也可以帮到更多的朋友。

谢谢!
4632 次点击
所在节点    问与答
4 条回复
paranoia
2014-12-13 19:39:19 +08:00
这个看看开源的框架就好了,基本都是大同小异。
RemRain
2014-12-13 20:40:05 +08:00
看情况,如果没有必要,就不要尝试去过滤或者转义,更不要尝试自己写算法转义。

存储方面,如果存储是 redis、文件等本身就是二进制安全,不存在“注入”的存储系统,直接存取就行;对于像 mysql 等存在注入风险的存储,就使用 sql 绑定,这就是最靠谱的方式,千万不要尝试自己去转义和过滤,即使是 php 自身的函数。

输出方面,和数据库同理。如果需要输出 html,请使用模板引擎,不要自己去转义拼输出,即使是使用 php 自身的函数也不行。如果是 ajax 请求,就好办了,直接使用 $("#id").val(text) 的方式修改对应的字段就行。

转义和过滤的真谛就是:不要使用转义和过滤,不到万不得已的时候,千万不要使用转义和过滤,即使是语言本身提供的函数(除非你知道自己到底在做什么),尤其不要自己去实现过滤和转义,更不要上网随意找一段防 sql 注入之类代码来用。
abelyao
2014-12-13 20:45:32 +08:00
@RemRain 非常感谢你的回答,写了几年程序,包括 1L @paranoia 说的参考别人的代码,虽然能对当前项目有个临时应对,但当需要做出修改或完善的时候,又经常是坑,这两天反过头来思考这个问题,来 v2ex 问这个,也是希望能看看大家的理解是怎样的。另外非常同意你最后一句话,如果不理解,随便拿一段来用绝对会有坑。
lincanbin
2014-12-13 20:45:45 +08:00
过滤主要分两类:SQL注入过滤、XSS过滤
SQL注入过滤现在只要用MySQLi或者PDO做参数绑定,就不用管了,Magic Quotes这种过滤方法和MySQL类都是在PHP 5.3就被废弃的特性了。
例如使用PDO: https://github.com/lincanbin/PHP-PDO-MySQL-Class

XSS过滤主要是对HTML进行转义,针对数据类型又分两种:
例如MarkDown之类的数据,直接进行HTML实体转义即可。
而HTML,除了Script标签还有各种on属性,都要过滤,一般用正则,写起来巨麻烦。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/153701

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX