restful api安全验证问题
没有绝对的安全,这个话题很深, 下文都是自己的一些理解,水平有限,如有勘误,希望大家予以指正。
由于 RESTful Api 是基于 Http 协议的 Api,是无状态传输,所以 只要和用户身份有关的 请求 都会带上身份认证信息。(很多时候客户端事先并不知道某个 api 后期会不会加入身份判断,所以我们一般都会选择每个请求都会带上认证信息,如果有的话。)
Http Basic Authentication
Http Basic 是一种比较简单的身份认证方式。 在 Http header 中添加键值对 Authorization: Basic xxx (xxx 是 username:passowrd base64 值)。
例如 username 为 zmk ,password 为 123456,请求则如下
GET /auth/basic/ HTTP/1.1
Host: xxxxx
Authorization: Basic em1rOjEyMzQ1Ng==
而Base64 的解码是非常方便的,如果不使用 Https ,相当于是帐号密码直接暴露在请求中。
危险性高,实际开发者使用的应该几乎为0。
顺便提下 DIGEST 认证,和 BASIC 认证相差无几,而且不适合 api 设计,实际又需要两次请求,首次请求,服务器端返回401,并且带上 nonce 值,然后客户端再利用 username + password + nonce 默认MD5之后再请求。对 http 请求的作用是仅仅防止二次请求,对身份认证并没有什么提升。
Cookie + Session
不知道是否应该这么称呼,只是觉得类似于 cookie 与 session 的机制。
原理即当客户端登录完毕之后,给客户端返回一个 cookie ,服务器端控制该 session 的有效期, 每次请求都带上该值,然后服务器端做验证,退出之后,客户端通知服务端端销毁 session ,自身销毁 cookie 。但是如果抓包获取到 cookie ,就能任意伪造请求了。
危险性高,实际开发估计使用得还不少。
Api Key + Security Key + Sign
下图是我们自己每次请求的身份认证的方式,如有不足,请大家指出。可以说是 JWT 的自定义版吧。

这里的认证逻辑即:
用户登录返回一个 api_key 和 security_key ;
然后客户端将 security_key 存在客户端;
当要发送请求之前,通过 function2 加密方法,把如图所示的五个值一起加密,得到一个 sign ;
发送请求的时候,则将除去 security_key 之外的值,以及 sign 一起发送给服务器端;
服务器端首先验证时间戳是否有效,比如是服务器时间戳5分钟之前的请求视为无效;
然后根据 api_key 验证 sercurity_key ;
最后验证 sign 。
是否需要加上时间戳验证?
上面的认证逻辑中加密得到签名的时候,把时间戳加进去是为了在一定程度上屏蔽了一些无效的请求,可以略去,也可以设计的更加严格。 如果想防止恶意的 api ddos 攻击,这一步验证肯定是不行的。需要做更多的验证,比如用户验证,ip 验证等。 可以参考 github 的 api 的设计 。它会在返回的 http 头信息里带上
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4999
表示这个接口在某一时间段内,该授权用户调用该接口的最大次数为5000次,该时间段内还剩余4999次。当然,这样的验证加上之后,在代码的执行效率上肯定会有所影响。
是否需要将 request_parameters 也加入到 sign 生成的算法之中?
也不是必须的,仅仅是为了请求的真实性,减少请求的伪造,比如 有人抓包拿到 http 请求之后,如果没有验证 sign 这步,那么别人就可以非常简单的修改请求的参数,而请求都会生效。
血的教训,自己经历的一个实际案例:
一个取消用户喜欢的标签的接口,该接口会向服务器端发送类似于 ids=1,2,3,4 这样的 request_parameters ,然后服务器端拿到这些 id 之后切割,然后将该用户和这些标签的关系从 user_tag 表中删除。某个周末,数据库服务器报警,而依照我们用户习惯,那个时间不存在流量高峰,这个报警很不正常,正准备处理,报警结束了,但是过了一段时间就有用户反应他们喜欢的标签都被删了。
通过查询数据库的慢日志,发现有很多注入的 sql。
DELETE FROM `user_tag` WHERE uid=4385328 AND tid=1 OR 14=14;
DELETE FROM `user_tag` WHERE uid=4385328 AND tid=1 OR 91=91;
原来 没有对切割之后的 id 没有做数字验证,估计黑客就是传的 ids=1 OR 14=14,2,3 ,而一个 delete 操作可能超时,他丫的就搞了很多次请求,真是够狠的。
幸运,数据库还有定时的打包备份,大部分用户的数据还是恢复了,同时修复了这一漏洞。
所以如果这里将 request_parameters 也加入到签名之中,就减少了伪造请求的可能性,但是无法杜绝,破坏者可能就非要黑你,又对逆向工程非常熟悉,找到我们加密算法的实现,依然可以未知出合法的签名,所以我们常说,服务器端永远不能相信客户端的请求都是安全的、合法的,需要做验证的都还是不能省略。
同时这( sign 算法)也造成了 api 接口调试的成本,api 测试工具必须也得实现那一套算法,或者是设置在开发环境下不做验证。我们在配置开发环境的时候则是 vpn 连测试服务器所在内网,然后进行测试,否则开发环境也存在被人利用的风险。
最近想拿一个小项目来试水RESTful Web API,项目只有几个调用,比较简单,但同样需要身份验证,如果是传统的网站的话,那不用说,肯定是用户名+密码在登录页获得登录Token,并把登录Token记在Cookie和Session中作为身份标识的这种方式,但现在不同了,关键是RESTful,这意味着我们设计出来的这些API是无状态的(Stateless),下一次的调用请求和这一次的调用请求应该是完全无关的,也就是说,正宗的RESTful Web API应该是每次调用都应该包含了完整的信息,没错,包括身份信息!
如何实现RESTful Web API的身份验证
最近想拿一个小项目来试水RESTful Web API,项目只有几个调用,比较简单,但同样需要身份验证,如果是传统的网站的话,那不用说,肯定是用户名+密码在登录页获得登录Token,并把登录Token记在Cookie和Session中作为身份标识的这种方式,但现在不同了,关键是RESTful,这意味着我们设计出来的这些API是无状态的(Stateless),下一次的调用请求和这一次的调用请求应该是完全无关的,也就是说,正宗的RESTful Web API应该是每次调用都应该包含了完整的信息,没错,包括身份信息!
那如何确保安全?传输时给密码做MD5加密?得了吧!这样做只能让你自己感觉“安全”点,其实没什么任何用处,利用现在的技术(有种叫什么Rainbow Table啥的来着?本人外行,不是很懂)很快就能算出明文密码了,而且如何防止挟持和重发攻击?
也许你想到了,SSL,如果你打算采用SSL,请忘记一切自行设计的加密方案,因为SSL已经帮你做好了一切,包括防止监听,防止挟持,防止重发……一切都帮你考虑好了,你大胆地把明文密码写在你的包中就OK了,我向你保证没问题。
但SSL的缺点是服务器端配置相对有点复杂,更关键的就是客户端对此支持可能不好,那你考虑一种自己的加密方法
restful api安全验证问题的更多相关文章
- (转载) RESTful API 设计指南
作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...
- RESTful Api 身份认证安全性设计
REST是一种软件架构风格.RESTful Api 是基于 HTTP 协议的 Api,是无状态传输.它的核心是将所有的 Api 都理解为一个网络资源.将所有的客户端和服务器的状态转移(动作)封装到 H ...
- 使用Flask设计带认证token的RESTful API接口[翻译]
上一篇文章, 使用python的Flask实现一个RESTful API服务器端 简单地演示了Flask实的现的api服务器,里面提到了因为无状态的原则,没有session cookies,如果访问 ...
- RESTful API 设计指南
转自:http://www.ruanyifeng.com/blog/2014/05/restful_api.html 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机. ...
- RESTful API 设计最佳实践
背景 目前互联网上充斥着大量的关于RESTful API(为了方便,以后API和RESTful API 一个意思)如何设计的文章,然而却没有一个"万能"的设计标准:如何鉴权?API ...
- RESTful API 设计指南 (转)
RESTful API 设计指南 2016-02-23 ImportNew (点击上方公号,可快速关注) 作者:阮一峰 链接:http://www.ruanyifeng.com/blog/2014/0 ...
- [转]10个有关RESTful API良好设计的最佳实践
Web API已经在最近几年变成重要的话题,一个干净的API设计对于后端系统是非常重要的. 通常我们为Web API使用RESTful设计,REST概念分离了API结构和逻辑资源,通过Http方法GE ...
- RESTFUL API 安全设计指南
RESTFUL API 安全设计指南 xxlegend · 2015/10/18 15:08 0x01 REST API 简介 REST的全称是REpresentational State Trans ...
- Yii2框架RESTful API教程(二) - 格式化响应,授权认证和速率限制
之前写过一篇Yii2框架RESTful API教程(一) - 快速入门,今天接着来探究一下Yii2 RESTful的格式化响应,授权认证和速率限制三个部分 一.目录结构 先列出需要改动的文件.目录如下 ...
随机推荐
- epoll对poll(select)的改进
select的几大缺点: 每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大: 每次调用select,内核需要遍历传递进来的所有fd(判断检测文件是否可用).有 ...
- ZooKeeper的基本概念(二)
第一篇博文,我们对Zookeeper有了一个简单的认识,而且比较浅显,易懂,这篇博文,我们了解它的基本概念,如下图所示: 了解它的基本概念,有助于我们后面的学习,虽然今天的文章都是概念性质的内容,但是 ...
- 使用文本用户界面(NMTUI)进行网络配置
NetworkManager 文本用户界面(TUI)工具 nmtui 可提供一个文本界面配置由 NetworkManager 控制的网络.该工具包含在 NetworkManager-tui 子软件包中 ...
- jquery中获取iframe的id的方法:
jquery中获取iframe的id的方法: var frameId = window.frameElement && window.frameElement.id || ''; al ...
- WORDPRESS登录后台半天都无法访问或者是访问慢的解决方法
wordpress登录后台如果打开速度慢,一般分为两部分,第一部分是php虚拟主机的原因,其中主机的原因,又分为很多种情况.第二部分就是WordPress程序本身的问题.这里无忧主机小编主要是讲第二部 ...
- django视图函数中 应用装饰器
from django.shortcuts import render, redirect, HttpResponse from .forms import LoginForm, Registrati ...
- php实现微信分享朋友圈
class JSSDK { private $appId; private $appSecret; public function __construct($appId, $appSecret) ...
- 20169211《Linux内核原理与分析》 第九周作业
一.Linux内核虚拟文件系统学习总结 Linux支持各种文件系统,Linux内核通过虚拟文件系统了对各种文件系统共性的进行抽象,并对外提供统一接口,从面向对象编程的角度来看,称为抽象文件系统更为合适 ...
- 安卓代码混淆(Android Studio)
Proguard是安卓提供的方便开发者对代码和apk进行保护和精简的工具,可在SDK/tools文件夹下找到. proguard的作用 : 1,代码混淆 2,精简代码,删掉没有用到的代码,减小ap ...
- 【知了堂学习笔记】java 编写几种常见排序算法
排序的分类: 一.交换排序 所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动. 1.冒泡 ...