REST API安全性设计指南。 REST的全名是REpresentational State Transfer,利用传统的Web特点,提出了既适用于客户端APP应用,也适用于服务器端APP应用的统一架构,大大统一了网站的架构设计。

目前,在三种主要的Web服务实现方案中,REST模式服务比复杂的SOAP和XML-RPC的比较更简洁,越来越多的Web服务开始使用REST进行设计和实现。 但是缺乏安全特性,《REST API 安全设计指南》是REST API安全设计的指南,建议网站后台设计和网站设计师们阅读。

1,REST API概述

REST的全名是REpresentational State Transfer,表示无状态传输,不需要session,所以每次请求都必须携带凭据。 rest基于http协议,也是无状态的。 因为只是架构方式,所以其安全特性都需要我们自己实现,没有现成的。 建议通过https协议发送所有请求。 rest风格的web服务概念的核心是“资源”。 资源可以用URI表示。 客户端使用HTTP协议中定义的方法向这些URIs发送请求。 当然,这些访问的“资源”的状态可能会发生变化。 HTTP请求的对应关系如下。

=========================================================

HTTP方法的行为示例

=========================================================

GET获取资源的信息http://xx.com/api/orders

GET获取某特定资源的信息http://xx.com/api/orders/123

开机自检创建新资源http://xx.com/api/orders

PUT更新资源http://xx.com/API /订单/123

删除资源http://xx.com/API /订单/123

=========================================================

请求的数据一般用json或xml格式表示,建议使用json。

2,身份证明

认证有多种方法,如http基本、http文摘、API密钥、自动、JWK等。 简单说明一下。

2.1 http基本版

由于REST是无状态的传输,所以每个请求都必须携带认证信息,认证的方式、认证的方式有各种各样的方式。 第一种是http basic,这种方式在客户端要求简单,在服务端的实现也非常简单,只需要简单地配置apache等web服务器就可以实现,所以对于简单的服务来说很方便。 但是,这种方式安全性低,只需要将用户名和密码base64代码放入header中。

base64编码前:基本管理员:管理员

base64编码后: Basic YWRtaW46YWRtaW4=

放入页眉:授权:基本型46 ywrtaw4=

不要忘记,正因为是简单的base64代码存储,所以在这种方法中必须注意ssl的使用。 否则你会裸奔。 有些产品也基于这样的方式,但没有使用apache的基本机制,而是自己编写认证框架。 原理相同,base64在一次请求中解码Authorization字段,并与凭据进行检查。 这种方式明显有问题,认证信息相当于明文发送,也没有暴力破解功能。

2.2 API密钥

API Key是指在通过用户认证后,服务器端向客户端分配API Key。 同样,http://example.com/api? key=dfkaj134,一般的处理流程如下。 简单的设计示例如下。 客户端:

REST协议(Restful API)-冯金伟博客园

服务器端:

REST协议(Restful API)-冯金伟博客园

客户端在服务器端注册,服务器端向客户端发送响应的api_key和security_key,注意不要泄露保存,然后客户端发送api_key、secrity_key、timey 基于rest_uri采用hmacsha256算法得到一个的服务端在收到这个请求后,首先验证api_key,如果存在,则取得该api_key的security_key,然后timestty 这样可以防止一些重放攻击,并防止中途的rest_api从url中作为/rest获取,这种

设计就防止了数据被篡改。 通过这种API Key的设计方式加了时间戳防止了部分重放,加了校验,防止了数据被篡改,同时避免了传输用户名和密码,当然了也会有一定的开销。

2.3 Oauth1.0a或者Oauth2

OAuth协议适用于为外部应用授权访问本站资源的情况。其中的加密机制与HTTP Digest身份认证相比,安全性更高。使用和配置都比较复杂,这里就不涉及了。

2.4 JWT

JWT 是JSON Web Token,用于发送可通过数字签名和认证的东西,它包含一个紧凑的,URL安全的JSON对象,服务端可通过解析该值来验证是否有操作权限,是否过期等安全性检查。由于其紧凑的特点,可放在url中或者 HTTP Authorization头中,具体的算法就如下图

REST协议(Restful API)-冯金伟博客园

3 授权

身份认证之后就是授权,根据不同的身份,授予不同的访问权限。比如admin用户,知性的爆米花,auditor用户都是不同的身份。简单的示例:

php
$roles = array(
‘ADMIN’=>array(
‘permit’=>array(‘/^((\/system\/(clouds|device)$/’), // 允许访问哪些URL的正则表达式
‘deny’=>array(‘/^(\/system\/audit)$/’) // 禁止访问哪些URL的正则表达式
),
‘AUDIT’=>array(
‘permit’=>array(‘/^(\/system\/audit)$/’),//允许访问的URL正则表达式
‘deny’=>array(‘/^((\/system\/(clouds|device).*)$/’)
)
);

上述是垂直权限的处理,如果遇到了平行权限的问题,如用户A获取用户B的身份信息或者更改其他用户信息,对于这些敏感数据接口都需要加上对用户的判断,这一步一般都在具体的逻辑实现中实现。

4 URL过滤

在进入逻辑处理之前,加入对URL的参数过滤,如

/site/{num}/policy

限定num位置为整数等,如果不是参数则直接返回非法参数,设定一个url清单,不在不在url清单中的请求直接拒绝,这样能防止开发中的api泄露。rest api接口一般会用到GET,POST,PUT,DELETE,未实现的方法则直接返回方法不允许,对于POST,PUT方法的数据采用json格式,并且在进入逻辑前验证是否json,不合法返回json格式错误。

5 重要功能加密传输

第一步推荐SSL加密传输,同时对于系统中重要的功能做加密传输,如证书,一些数据,配置的备份功能,同时还得确保具备相应的权限,这一步会在授权中涉及。

6 速率限制

请求速率限制,根据api_key或者用户来判断某段时间的请求次数,将该数据更新到内存数据库(redis,memcached),达到最大数即不接受该用户的请求,同时这样还可以利用到内存数据库key在特定时间自动过期的特性。在php中可以使用APC,Alternative PHP Cache (APC) 是一个开放自由的PHP opcode 缓存。它的目标是提供一个自由、 开放,和健全的框架用于缓存和优化PHP的中间代码。在返回时设置X-Rate-Limit-Reset:当前时间段剩余秒数,APC的示例代码如下:

php
Route::filter(‘api.limit’, function()
{
$key = sprintf(‘api:%s’, Auth::user()->api_key);
// Create the key if it doesn’t exist
Cache::add($key, 0, 60);
// Increment by 1
$count = Cache::increment($key);
// Fail if hourly requests exceeded
if ($count > Config::get(‘api.requests_per_hour’))
{
App::abort(403, ‘Hourly request limit exceeded’);
}
});

7 错误处理

对于非法的,导致系统出错的等请求都进行记录,一些重要的操作,如登录,注册等都通过日志接口输出展示。有一个统一的出错接口,对于400系列和500系列的错误都有相应的错误码和相关消息提示,如401:未授权;403:已经鉴权,但是没有相应权限。如不识别的url:

{“result”:”Invalid URL!”}

,错误的请求参数

{“result”:”json format error”}

,不允许的方法:

{“result”:”Method Not Allowed”}

,非法参数等。上面所说的都是单状态码,同时还有多状态码,表示部分成功,部分字符非法等。示例如下:

HTTP/1.1 207 Multi-Status
Content-Type: application/json; charset=”UTF-8″
Content-Length: XXXX
{
“OPT_STATUS”: 207
“DATA”: {
“IP_ADDRESS”: [{
“INTERFACE”: “eth0”,
“IP_LIST”:[{
“IP”: “192.168.1.1”,
“MASK”: “255.255.0.0”,
“MULTI_STATUS”: 200,
“MULTI_RESULT”: “created successfully”
},{
“IP”: “192.167.1.1”,
“MASK”: “255.255.0.0”,
“MULTI_STATUS”: 409,
“MULTI_RESULT”: “invalid parameter”
}]
}]
},

8 重要ID不透明处理

在系统一些敏感功能上,比如/user/1123 可获取id=1123用户的信息,为了防止字典遍历攻击,可对id进行url62或者uuid处理,这样处理的id是唯一的,并且还是字符安全的。

9 其他注意事项

(1)请求数据,对于POST,DELETE方法中的数据都采用json格式,当然不是说rest架构不支持xml,由于xml太不好解析,对于大部分的应用json已经足够,近一些的趋势也是json越来越流行,并且json格式也不会有xml的一些安全问题,如xxe。使用json格式目前能防止扫描器自动扫描。 (2)返回数据统一编码格式,统一返回类型,如Content-Type: application/json; charset=”UTF-8″ (3)在逻辑实现中,json解码之后进行参数验证或者转义操作,第一步json格式验证,第二步具体参数验证基本上能防止大部分的注入问题了。 (4)在传输过程中,采用SSL保证传输安全。 (5)存储安全,重要信息加密存储,如认证信息hash保存。

总之,尽量使用SSL。