RESTful API

REST API 安全性

2016-03-29  本文已影响1674人  竹天亮

由于REST API是系统暴露给外界的接口,所以安全性非常重要。安全不只是单纯的加密和解密,而是一致性(integrity),机密性(confidentiality)和可用性(availibility)。

一、 请求数据验证

数据流入REST API的第一步请求数据的验证来保证安全性。我们可以把数据验证看做一个巨大的漏斗,把不必要的访问统统过滤在第一线:

二、数据完整性验证

REST API往往需要对backend的数据进行修改。而修改是个可怕的操作,我们不仅要保证正常的服务请求能够正常处理,还要防止各种潜在的攻击,如replay。
数据完整性验证的底线是:保证要修改的数据和服务器里的数据是一致的---通过Etag来完成。

Etag可以认为是某个资源的版本号。当客户端请求某个资源的时,该资源的Etag一同被返回,而当客户端需要修改该资源时,需要通过"If-Match"来提供这个Etag。服务器检查客户端提供的Etag是否和服务器统一资源的Etag相同,如果相同,才进行修改,否则返回412 precondition failed。

使用Etag可以防止错误更新。比如A拿到了Resource X的Etag X1,B也拿到了Resource X的Etag X1。B对X做了修改,修改后系统生成的新的Etag是X2。这时A也想更新X,由于A持有旧的Etag,服务器拒绝更新,直至A重新获取了X后才能正常更新。

Etag类似一把锁,是数据完整性的最重要的一道保障。Etag能把绝大多数integrity的问题扼杀在摇篮中,当然,race condition还是存在的:如果B的修改还未进入数据库,而A的修改请求正好通过了Etag的验证时,依然存在一致性问题。这就需要在数据库写入时做一致性写入的前置检查。

三、访问控制

REST API需要清晰定义哪些操作能够公开访问,哪些操作需要授权访问。一般而言,如果对REST API的安全性要求比较高,那么,所有的API的所有操作均需得到授权。

在HTTP协议之上处理授权有很多方法,如HTTP BASIC Auth,OAuth,HMAC Auth等,其核心思想都是验证某个请求是由一个合法的请求者发起。Basic Auth会把用户的密码暴露在网络之中,并非最安全的解决方案,OAuth的核心部分与HMAC Auth差不多,只不过多了很多与token分发相关的内容。这里我们主要讲讲HMAC Auth的思想。

回到Security的三个属性:一致性,机密性,和可用性。HMAC Auth保证一致性:请求的数据在传输过程中未被修改,因此可以安全地用于验证请求的合法性。

HMAC主要在请求头中使用两个字段:Authorization和Date(或X-Auth-Timestamp)。Authorization字段的内容由":"分隔成两部分,":"前是access-key,":"后是HTTP请求的HMAC值。在API授权的时候一般会为调用者生成access-key和access-secret,前者可以暴露在网络中,后者必须安全保存。当客户端调用API时,用自己的access-secret按照要求对request的headers/body计算HMAC,然后把自己的access-key和HMAC填入Authorization头中。服务器拿到这个头,从数据库(或者缓存)中取出access-key对应的secret,按照相同的方式计算HMAC,如果其与Authorization header中的一致,则请求是合法的,且未被修改过的;否则不合法。


在做HMAC的时候,request headers中的request method,request URI,Date/X-Auth-Timestamp等header会被计算在HMAC中。将时间戳计算在HMAC中的好处是可以防止replay攻击。客户端和服务器之间的UTC时间正常来说偏差很小,那么,一个请求携带的时间戳,和该请求到达服务器时服务器的时间戳,中间差别太大,超过某个阈值(比如说120s),那么可以认为是replay,服务器主动丢弃该请求。

使用HMAC可以很大程度上防止DOS攻击 —— 无效的请求在验证HMAC阶段就被丢弃,最大程度保护服务器的计算资源。

四、HTTPS

HMAC Auth尽管在保证请求的一致性上非常安全,可以用于鉴别请求是否由合法的请求者发起,但请求的数据和服务器返回的响应都是明文传输,对某些要求比较高的API来说,安全级别还不够。这时候,需要部署HTTPS。在其之上再加一层屏障。

五、其他

做到了接口一致性(符合RFC)和安全性,REST API可以算得上是合格了。当然,一个实现良好的REST API还应该有如下功能:

各个社区里面比较成熟的REST API framework/library:
  • Python: django-rest-framework(django),eve(flask)。各有千秋。可惜python没有好的类似webmachine的实现。

转: 『程序人生』(搜索微信号 programmer_life

上一篇 下一篇

猜你喜欢

热点阅读