api-gateway实践(19)HTTP请求防篡改

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了api-gateway实践(19)HTTP请求防篡改相关的知识,希望对你有一定的参考价值。

一、概念和定义

1、什么是重放攻击?

我们在设计接口的时候,最担心一个接口被别有用心的用户截取后,用于重放攻击。重放攻击是什么呢?就是把请求被原封不动地重复发送,一次,两次...n次。

2、重放攻击造成的后果

一般的请求被提交到后台执行,先会经过【页面验证】后提交给【后台逻辑】,提交给【后台逻辑】过程中请求可能会被被拦截,

  • 如果这个【后台逻辑】是插入数据库操作,就很容易造成多条重复的数据插入数据库。
  • 如果这个【后台逻辑】是查询数据库操作,就可能导致反复查询,数据库被堵住等情况。

所以,我们需要一种防重放的机制来做请求验证。

二、解决方案

1、客户端(携带timestamp+nonce)

我们常用的防止重放的机制是使用timestamp和nonce来做的重放机制。

1.1、timestamp

timestamp用来表示请求的当前时间戳,这个时间要事先和服务器时间戳校正过。我们预期正常请求带的时间戳会是不同的,如:假设正常人每秒至多会做一个操作。

每个请求携带的时间戳不能和当前时间距离很近,即不能超过规定时间,如60s。这样请求即使被截取了,也只能在有限时间(如:60s)内进行重放,过期就会失效。

1.2、nonce

仅仅提供timestamp还是不够的,我们还是提供给攻击者60s的可攻击时间了。要避免60秒内发生攻击,我们还需要使用一个nonce随机数。

nonce是由客户端根据随机生成的,比如 md5(timestamp+rand(0, 1000),正常情况下,在短时间内(比如60s)连续生成两个相同nonce的情况几乎为0。

2、服务端(验证时间是否超限,检查签名)

服务端第一次在接收到这个nonce的时候做下面行为:

1 去redis中查找是否有key为nonce:{nonce}的string

2 如果没有,则创建这个key,把这个key失效的时间和验证timestamp失效的时间设置一致,比如是60s。

3 如果有,说明这个key在60s内已被使用过了,这个请求就可以判断为重放请求。

3、方案流程

 

http://www.xxxx.com?userId=123&userName=zhangsan&timestamp=1480556543&nonce=43f34f33&sign=80b886d71449cb33355d017893720666

在这个请求中,userId和userName是真正需要传递的业务参数,timestamp,nonce,sign都是为了签名和防重放使用。

timestamp是发送请求时间,nonce是随机串,sign是对uid,timestamp,nonce(对于一些rest风格的api,建议业务参数一起签名)。

服务端接到这个请求的处理逻辑:

  • 先验证sign签名是否合理,证明请求参数没有被中途篡改
  • 再验证timestamp是否过期,证明请求是在最近60s被发出的
  • 最后验证nonce是否已经有了,证明这个请求不是60s内的重放请求

以上是关于api-gateway实践(19)HTTP请求防篡改的主要内容,如果未能解决你的问题,请参考以下文章

api-gateway实践新服务网关 - 网关请求监控统计

api-gateway实践(15)guava-19.0和google-collections-1.0 的 ImmutableSet 类冲突

api-gateway实践网关服务集成验证

api-gateway实践(15)新服务网关 -运行环境搭建

api-gateway实践新服务网关 - 测试发布(服务端API)

api-gateway实践(14)新服务网关 - 演示环境搭建