HTTP协议扫盲(五)HTTP请求防篡改
相关链接:
http://www.cnblogs.com/ziyi--caolu/p/4742577.html
请求防重放:http://www.2cto.com/kf/201612/573045.html
登录防重放:http://huangqiqing123.iteye.com/blog/2033014
一、概念和定义
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×tamp=1480556543&nonce=43f34f33&sign=80b886d71449cb33355d017893720666
在这个请求中,userId和userName是真正需要传递的业务参数,timestamp,nonce,sign都是为了签名和防重放使用。
timestamp是发送请求时间,nonce是随机串,sign是对uid,timestamp,nonce(对于一些rest风格的api,建议业务参数一起签名)。
服务端接到这个请求的处理逻辑:
- 先验证sign签名是否合理,证明请求参数没有被中途篡改
- 再验证timestamp是否过期,证明请求是在最近60s被发出的
- 最后验证nonce是否已经有了,证明这个请求不是60s内的重放请求

4、方案分析
我们将每次请求的nonce参数存储到一个“集合”中,可以json格式存储到缓存中。
每次处理HTTP请求时,首先判断该请求的nonce参数是否在该“集合”中,如果存在则认为是非法请求。
我们在timestamp方案的基础上,加上nonce参数,因为timstamp参数对于超过60s的请求,都认为非法请求,所以我们只需要存储60s的nonce参数的“集合”即可。
nonce的一次性可以解决timestamp参数60s的问题,timestamp可以解决nonce参数“集合”越来越大的问题。
HTTP协议扫盲(五)HTTP请求防篡改的更多相关文章
- 基于Volley,Gson封装支持JWT无状态安全验证和数据防篡改的GsonRequest网络请求类
这段时间做新的Android项目的client和和REST API通讯框架架构设计.使用了非常多新技术,终于的方案也相当简洁优雅.client仅仅须要传Java对象,server端返回json字符串, ...
- WebApi系列~安全校验中的防篡改和防复用
回到目录 web api越来越火,因为它的跨平台,因为它的简单,因为它支持xml,json等流行的数据协议,我们在开发基于面向服务的API时,有个问题一直在困扰着我们,那就是数据的安全,请求的安全,一 ...
- cookie安全隐患及防篡改机制
Cookie和Session是为了在无状态的HTTP协议之上维护会话状态,使得服务器可以知道当前是和哪个客户在打交道.本文来详细讨论Cookie和Session的实现机制,以及其中涉及的安全问题. 因 ...
- http协议(二)请求和响应报文的构成
http协议用于客户端和服务器之间的通信,请求访问资源的一方称为客户端,而提供资源响应的一方称为服务器端. 下面就是客户端和服务端之间简单的通信过程 PS:请求必须从客户端建立通信,服务端没收到请求之 ...
- 01WebApi防篡改机制---HMAC机制
防篡改,顾名思义就是防止有人恶意篡改请求数据URL以达到恶意攻击的目的,那要怎么才能实现这样的目的呢? 很简单,将要请求的数据加上合作号.合作Key按规则组织成一个字符串,获取对应的MD5摘要,然后将 ...
- 网站如何防Session冒名顶替和cookie防篡改
做网站难免要面对安全性的问题,诸如sql注入拉,cookie冒名拉,等等,sql注入算是老生常谈,翻翻旧账有不少优秀的帖子在说明这个问题,所以我们来说说Session冒名顶替的风险以及应对的办法. 首 ...
- WebAPI 用户认证防篡改实现HMAC(二)签名验证 AbsBaseAuthenticationAttribute--转
public class ActionFilter : ActionFilterAttribute { public override void OnActionExecu ...
- 使用数字签名实现数据库记录防篡改(Java实现)
本文大纲 一.提出问题 二.数字签名 三.实现步骤 四.参考代码 五.后记 六.参考资料 一.提出问题 最近在做一个项目,需要对一个现成的产品的数据库进行操作,增加额外的功能.为此,需要对该产品对数据 ...
- Cookie防篡改机制
一.为什么Cookie需要防篡改 为什么要做Cookie防篡改,一个重要原因是 Cookie中存储有判断当前登陆用户会话信息(Session)的会话票据-SessionID和一些用户信息. 当发起一个 ...
随机推荐
- NYOJ 题目12喷水装置(二)
#include<iostream> #include<algorithm> #include<cmath> using namespace std; struct ...
- 功能性AI术语表
算法:一套计算机要遵循的指令.一个算法可以是一个简单的单步程序也可以是一个复杂的神经网络,但是通常被用来指一个模型. 人工智能:这是一个统称.广义上说,软件意味着模仿或取代人类智能的各个方面.人工智能 ...
- redis分片和哨兵
1 Redis的使用 1.1 Redis入门案例 1.1.1 什么样的数据使用缓存 说明:使用缓存其实为了减少用户查询数据库的时间.如果数据频繁的变更.不适用缓存.缓存中的数据应该保存修改频率不高的数 ...
- JSP中动态include和静态include区别
静态include(<%@ include file=""%>): 静态include(静态导入)是指将一个其他文件(一个jsp/html)嵌入到本页面 jsp的inc ...
- TCP 详解
计算机网络中比较中要的无非就是 TCP/IP 协议栈,以及应用层的 HTTP 和 HTTPS . 前几天一直炒的的比较火的就是 HTTP/2.0 了,但是其实 HTTP/2.0 早在2015年的时候就 ...
- 【Docker】 积累
■ 磁盘空间和docker资源之间的关系 通过docker info | grep Space可以看到Docker占据的磁盘空间的信息.其中Data Space Used表示实际上docker资源占用 ...
- SQL注入之Sqli-labs系列第二篇
废话不在多说 let's go! 继续挑战第二关(Error Based- String) 同样的前奏,就不截图了 ,and 1=1和and 1=2进行测试,出现报错 还原sql语句 查看源代码 ...
- 功能测试很low?不能升级到高级测试工程师?
功能测试很low?不能升级到高级测试工程师? 功能测试很low?功能测试很简单?功能测试就是黑盒测试?功能测试没有技术含量?功能测试工资低?只会功能测试没有竞争力?功能测试这活初中生都可以干?功能测试 ...
- 多线程 Synchronized关键字和Lock
Synchronized 分为实例锁和全局锁. 实例锁为 synchronized(this) 和 非static synchronized方法. 也加对象锁. 只要一个线程访问这类的一个syn ...
- runtime.getruntime.availableprocessors
1:获取cpu核心数: Runtime.getRuntime().availableProcessors(); 创建线程池: Executors.newFixedThreadPool(nThreads ...