2020 年不太平,各种牛鬼蛇神轮番登场。可能有点忘乎所以,不知哪句评论错了,被知乎封禁了一周。还好,冷静一下,再不参与zz相关的话题了。
说回正题,作为码农,网络安全一直以来是个麻烦。最近,在我司维护的一个很旧很旧的网站上,发现有人通过富文本编辑器用的上传接口,偷偷上传了一些不良内容的网页文件。
通常,我们使用富文本编辑器,以便用户可以发布图文混排的内容,甚至许可添加点附件。但方便的同时,也带来了一些安全隐患,如程序员比较熟悉的跨站攻击、点击劫持等。上传,尤其是允许上传 html 文件,这个危害是非常大的。首先,既然是 HTML,意味着可嵌入任意 JS,跨站攻击、点击劫持自然不在话下;其次,如果您的网站在搜索引擎排名不错,对方可通过 SEO 的形式,将您的网站变成一个倒流通道;如果您的网站涉及zf相关机构,对方放点黄赌毒内容,也会严重影响到某些单位的形象。
好在大部分富文本编辑器默认只提供插入图片功能,给出的服务端上传示例代码,也限定为仅支持上传图片。但也有一些功能较全的富文本编辑器,默认提供插入附件的功能,上传代码可能支持 pdf/txt/html 等浏览器可预览(执行)的文件类型。我们网站用的某款编辑器是 5、6 年以前加入的,一直也没升级,而新版编辑器早已移除默认的 html 类型。
先来说下如何利用富文本的上传漏洞往网站上传文件。富文本编辑器插入图片、视频、音频、附件,实际插入的是图片、视频、音频、附件的网址,包裹为 <img><video><audio> 等 html 标签。要么直接给一个网址,要么上传后返一个网址。对于后者,服务端需要给出一个接口,提供上传文件功能,并返回文件存入服务器后的网址。以此来看,入侵者完全不必管前端富文本编辑器的逻辑,直接利用上传接口,上传文件、拿到网址。
这要如何防范呢?我们已经知道了,入侵者根本不用管你前端用的什么编辑器、JS如何配置,他只需要探查到你的上传接口即可,因此,任何在前端限制不可插入资源都是无效的。防御方面,我认为有几点,各有利弊:
1、防盗链,为上传目录的请求加个过滤层,当程序发现 referer 不是您的域名时阻断,避免外链造成恶劣影响。这显然避免不了不良内容出现在站内。
2、临时文件,插入时先将文件上传到临时目录,待提交后内容校验通过,再转移到目标目录,同时替换内容中的网址。临时目录内文件超时自动删除。
3、图文分离,彻底抛弃富文本,或富文本仅能调节文字排版,图片、附件等用额外的字段存储,也就是说,文件与表单数据是绝对捆绑的,表单校验不通过,入侵方就不可能拿到文件网址。
4、文件转码,图片直接转为 base64 文本,利用 <img src="data:image/png;base64,xxx"/> 的形式与内容混合在一起;如果是图文分离模式,可将文件存入对应的 Binary 类型字段。这也是保障文件与表单数据捆绑,便于发现,更易封禁。缺点是占用数据库空间,也不便于直接使用主流 HTTP 服务的缓存功能。
以上后 3 条依然需要人工审查。现如今也出现一些 AI 内容审核的东西,但训练是件麻烦事,小企业在这方面耗费大量人力物力就得不偿失了。而阿里、百度等也有提供内容审核方面的接口,文本、图片均可,有些接口检查速度达毫秒级,完全可以封装到服务端的表单校验逻辑里。当然,天下没有免费的午餐。如果您的内容完全由内部人员维护,只用规避偷偷上传,限制某类用户可用,就够了。
本话题由富文本编辑器引起,那么,是否不用富文本编辑器就万事大吉了?从技术上来说,只要您的网站开放或半开放上传,依然可能存在被上传不良、黑链等内容的图片、文件,按照现行法律法规,这些文件只要在您服务器上,就脱不了干系,只是会不会被发现的问题。
以上面第 3 条为例,图文分离,当运营人员发现有个图片内容不良,他删除了此条数据,或标识为不公开,外部无法再浏览,通过条目ID打开也显示不存在或不可见,但对一般编程习惯来说,文件可能依然保留在原处。破坏的一方依然可以利用审查前拿到的文件网址,继续通过外部网页指向您的服务器。哪天那个黑站被端了,发现那些资源还都存在您那,冤不冤呀!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。