微信公众平台接入的安全性

最近微信公众平台非常红火,基于公众平台的接入应用也越来越多。不过在处理接入入口的安全问题上,可能不是那么的严谨。现在我们来讨论下如何保证微信公众平台接入的安全性。

根据微信官方提供的消息接口指南,微信公众平台分为接入和使用两步。接入程序官方提供了一个简单的例子,我们来回顾一下接入认证的方式:

提交接入申请后,微信公众平台将会发起一个接口认证的请求到接口地址,使用GET方式请求,并携带这些参数:

参数 描述
signature 微信加密签名
timestamp 时间戳
nonce 随机数
echostr 随机字符串

接入申请到达后,接口端需要验证signature的有效性,验证通过后,将echostr参数原样输出返回给微信平台。至于signature的生成规则,则有如下的定义:

加密/校验流程:
1. 将token、timestamp、nonce三个参数进行字典序排序
2. 将三个参数字符串拼接成一个字符串进行sha1加密
3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

这里需要注意官方消息接口指南中的一个疏漏,就是并没有提示任何一次请求都必须校验签名。一些开发者可能忽略了这个细节,在未验证签名的情况下就处理了请求。这一点需要格外注意。

然而,这并不意味着,签名验证通过,请求就是安全的。这里有一种重现攻击的办法——截获(或者通过访问日志泄露)微信服务器和接口服务器的请求,使得某次的请求参数泄露。如果单纯按照上面的办法验证签名,这意味着任何一次请求的参数在将来的任何时候,都是有效的。

为了防止签名的重用,我们可以进行以下两点防范措施:

  • 检查timestamp有效性。由于服务器之间存在时差,所以timestamp只要保证一个窗口时间范围内有效即可。
  • signature防重用。由于两次请求产生相同签名的几率非常小,所以我们只要将使用过的签名暂时屏蔽。这可能需要借助memcache这种K-V缓存进行。屏蔽时间稍大于上面的timestamp窗口时间即可。

但是这样还不足以保证消息的彻底安全,因为上面的手段还无法防止“中间人攻击”。

什么是“中间人攻击”呢,举个例子,客户端和服务器端之间的通讯,被恶意的第三方加上了透明代理,他们彼此并不知道这个代理的存在。因此这个代理人可以偷偷获取通讯数据,甚至篡改数据。中间人攻击多见于针对SSL通讯协议的攻击。由于SSL通讯链路加密,第三方无法直接解密数据。通过中间人攻击,透明地代理SSL访问(中间人也持有合法的SSL证书),在神不知鬼不觉中,就监听了加密通讯。在这里也提醒大家,即使使用HTTPS方式访问网络,也不一定完全安全,还需要谨慎的验证服务器的证书信息,是否和期望的一致。当然,双向证书模式认证,可以避免这个攻击风险。

上面的话说的有点远了。由于signature的生成并不包含报文信息,所以即使signature正确,也无法保证通讯报文未被篡改。为了一定程度上解决这个问题,请严谨地验证微信消息请求中的CreateTime字段,和timestamp字段是否在合理的时间窗内,这样可以降低篡改消息攻击的风险,但是并不能完全消除。

由此可见,微信公众平台消息接入,只适用于那些并不机要的消息传递。在真正的使用中,也推荐只进行诸如非敏感信息查询等服务。

参考资料:

微信公众平台开发接口开发指南:http://mp.weixin.qq.com/wiki/index.php

微信公众平台接入的安全性》上有3条评论

评论已关闭。