[TOC]

思考

写了那么多小程序,你思考过小程序的安全问题么?
为什么小程序支持跨域?
小程序中有xss,crsf攻击吗?
为什么小程序只支持request cookie,不支持response set cookie呢?
为什么小程序不支持动态加载js?什么叫动态加载js?eval和new Function有什么可怕之处?
真的没有绕过小程序审核热更新的方法吗?
小程序的登录设计有哪些安全考虑?
可以肉眼区分一个页面是小程序还是web-view吗?
今天我们就来深入理解小程序的安全设计和管控。
先限定下范围,虽然头条小程序,支付宝小程序,QQ小程序层出不穷,但本文主要从微信小程序说起。
小程序中也支持web-view,内嵌网页这类不在本文讨论范围之中,因为和浏览器是一样的,还是不支持跨域,会有XSS等。

分析

为什么小程序支持跨域?
我通常和后端小伙伴这样解释,我们可以理解小程序是类似native的,所以不需要考虑跨域问题。
再解释清楚一点就是:小程序的网络请求是通过native的能力来中转后发出的,而不是直接在webview中发出的。
那我们再思考下,为什么native支持跨域而前端限制那么多?
个人感觉原因如下:
1.因为前端代码是裸奔状态,用户(或者坏人)输入网址后F12就可以一览无余你的源码,而客户端的代码是编译好的,没那么容易被反编译,看清源码,所以webpack打包会生成source map,上线时最好删掉source map文件,否则坏人轻轻松松就能get到你的源码。
2.了解源码之后,前端代码存在各种被注入的可能性,一不小心就location.href到别的页面,一不小心就document.cookie获取走了cookie,或者给你做个假的登录页窃取你的密码,可以参照文章:万物皆可hook
3.浏览器tab页的存在,用户身份通常通过cookie来存储,即使tab页之间没有关系,坏人页面依然有办法窃取你的cookie。攻击形式太多样了,非常需要同源策略(跨域)的限制。
既然说到了cookie,小程序中有个重要的限制就是request中可以支持cookie但是response中不支持cookie,这又是什么考虑呢?
我们知道,在浏览器中发出请求时会自动携带该域名下的cookie,同域名的js,img,css请求都会带上cookie,但是因为小程序的网络请求是通过native来转发的,并不是之前常用的AJAX,小程序语法中我们必须手动在header中设置cookie。

12345678910 wx.request({ method: ‘GET’, url: ‘evacoder.com/users’, data: {}, header: { ‘content-type’: ‘application/x-www-form-urlencoded’, // 设置cookie ‘cookie’: ‘userId=12345’ },})

请求是native代为转发,那接受响应的实际是native,经过处理后再传递给webview,wx.request成功回调中没有返回cookie,小程序也直接禁用了DOM,BOM相关的所有方法,document.cookie根本无法调用,微信爸爸不提供cookie的返回咱也没办法。
发送cookie必须手动设置,获取不到document.cookie以及响应中的cookie,小程序中应该是不存在CSRF了。
当然还有更严格的限制,要调用某域名的接口必须在该域名下放校验文件,所以不经过同意别人的小程序没法调用你的接口,在你的小程序坏人也没法把窃取到的信息发到他的域名。
小程序是否存在xss呢?
xss即js代码注入,前端要做的是不信任任何用户的输入,将所有的特殊字符如<>/%都进行过滤,尽量不要使用eval,innerHTML。比如在博客留言中留下<script>location.href='https://badman.com'</script>后,这样每个访问这个页面的人都会被导流到坏人的页面(或者被窃取cookie等造成损失)。
我觉得总会有些小白不过滤吧,试了几个没啥用户的个人小程序,填写<script>location.href='https://badman.com'</script>果然可以提交成功,但重新进入这个页面并没有跳转到badman页面。
小程序最终也是编译成了html,DOM中的