安全矩阵

 找回密码
 立即注册
搜索
查看: 4767|回复: 0

PHP安全:API接口访问安全

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2020-10-17 20:38:35 | 显示全部楼层 |阅读模式
原文链接:PHP安全:API接口访问安全

由于HTTP是无状态的,因此正常情况下在浏览器浏览网页,服务器都是通过访问者的会话ID(Session ID)来辨别客户端的身份,当客户端与服务器交互的时候,服务端会拿自己的Session ID与客户端的进行对比,这样客户端再次访问服务器即可识别用户的身份。


但是对于API服务器,不能让访问者使用Session ID进行访问,这样既不安全,也不友好。由HTTP进行通信的数据大多是未经加密的明文,包括请求参数、返回值、Cookie、Header等数据,因此,外界通过对通信的监听,便可轻而易举根据请求和响应双方的格式,伪造请求与响应,修改和窃取各种信息。

所有的认证信息一定要经过加密处理,禁止身份认证信息进行明文传输,避免被攻击者窃取。

1、IP白名单

如果接口只是针对个别业务使用,建议添加IP白名单。通过IP白名单来限制访问源,可以有效避免外部恶意攻击者的请求。
  1. <?php

  2. $ip_white_list=array('1.1.1.1','2.2.2.2','3.3.3.3'); // IP白名单

  3. // 获取客户端IP

  4. if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {

  5. $arr=explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);

  6. $pos=array_search('unknown',$arr);

  7. if(false!==$pos) unset($arr[$pos]);

  8. $ip=trim($arr[0]);

  9. }else if (isset($_SERVER['HTTP_CLIENT_IP'])) {

  10. $ip=$_SERVER['HTTP_CLIENT_IP'];

  11. }else if (isset($_SERVER['REMOTE_ADDR'])) {

  12. $ip=$_SERVER['REMOTE_ADDR'];

  13. }else if (isset($_SERVER['REMOTE_ADDR'])) {

  14. $ip=$_SERVER['REMOTE_ADDR'];

  15. } else {

  16. $ip=null;

  17. }

  18. if(!in_array($ip,$ip_white_list)) { // 判断客户端IP是否在白名单中

  19. echo '<h1 align=center> HTTP/1.1 403 Forbidden</h1>';

  20. header('HTTP/1.1 403 Forbidden');

  21. }

  22. ?>
复制代码

2、摘要认证

一般情况下需要客户端提供一个KEY和一个SECRET串(每个KEY与用户是一对一关联的)来识别请求者的身份,并且需要对每次请求进行认证,来判断发起请求的是不是就是该用户,以及请求信息是否被篡改。一般采用对请求信息(主要是URL和参数)进行摘要认证的方法来解决。由于摘要算法的不可逆性,因此这种方式能够在一定程度上防止信息被篡改,从而保障通信的安全。

应用程序首先需要给使用API的用户分配KEY和SECRET。可以使用MD5或SHA算法生成摘要,然后按照表1所列的流程进行摘要加密和认证。

表1  摘要加密和认证流程

由于HTTP都是明文请求,虽然可以通过摘要进行一定的安全保证确保信息不被篡改,但是无法保证每次请求的唯一性,也就是如果请求数据被别人获取再次请求,此时也可能带来很严重的安全性问题。于是便需要用户在每次请求中设置一个递增的参数Nonce,来确保每次请求都是唯一的。不过这样也可能带来一个问题,就是如果用户近乎同时发起A和B两个请求,由于网络阻塞,可能后发起的B先到达服务器,这样当A达到的时候,服务器会认为A的Nonce已过期而拒绝。为了解决这样的问题,允许用户设置一个expire值来避免Nonce认证带来的问题。

3、OAuth认证

开放授权(Open Authorization,OAuth)是一个开放标准,为用户资源的授权提供了一个安全、开放而又简易的标准。不用将用户名和密码提供给第三方应用,就可以允许用户让第三方应用访问该用户在某一网站上存储的用户资源。OAuth的基本流程如图1所示。

图1  OAuth基本流程

1)用户打开应用以后,应用要求用户给予授权。

2)用户同意给予第三方应用授权。

3)应用使用上一步获得的授权,向认证服务器申请令牌。

4)认证服务器对第三方应用进行认证以后,确认无误,同意发放令牌。

5)应用使用令牌,向资源服务器申请获取资源。

6)资源服务器确认令牌无误,同意向应用开放资源。

在第二步中,用户给予应用进行授权。有了这个授权以后,应用就可以获取令牌,进而凭令牌获取资源。

应用获取授权有4种模式,它必须得到用户的授权,才能获得令牌。在OAuth 2.0中定义了4种授权模式。

(1)授权码模式

授权码模式(Authorization Code)是功能最完整、流程最严密的授权模式之一。它的特点就是通过应用的后端服务器,与“服务提供商”的认证服务器进行互动。授权码模式如图2所示。

图2  授权码模式

1)用户访问应用。

2)应用判断用户是否登录,如果未登录则将用户导向认证服务器。

3)用户选择是否给予当前应用授权。如果用户给予授权,认证服务器则发放授权码。

4)认证服务器将用户导向该应用事先指定的“重定向URL”,同时附上刚才的授权码。

5)应用收到授权码,使用授权码向认证服务器申请令牌。这一步是在应用的后端的服务器上完成的,对用户不可见。

6)认证服务器核对授权码,确认无误后,向应用发送访问令牌(Access Token)或更新令牌(Refresh Token)。

(2)隐式授权模式

隐式授权(Implicit Grant)模式也叫作client-side模式,该模式不通过第三方应用程序的服务器,主要用在没有或无法安全存储访问令牌的使用场景,适用于需要通过客户端访问的方式,例如需要通过浏览器的JavaScript代码,或者计算机/移动终端上的客户端访问时。隐式授权模式如图3所示。

图3  隐式授权模式

1)用户访问应用。

2)应用将用户导向认证服务器。

3)用户同意授权,认证服务器将用户导向应用指定的“重定向URL”,并在URL的Url_Hash部分包含了访问令牌,用户通过解析脚本对Url_Hash解析获取令牌。

(3)密码模式

密码模式(Resource Owner Password Credentials),即用户将令牌发到应用中,用户向应用提供自己的用户名和密码。应用使用这些信息,向“服务提供商”索要授权。

在这种模式中,用户必须把自己的密码给应用,但是应用不得储存密码。这通常用在用户对应用高度信任的情况下,比如应用是操作系统的一部分,或者由一家著名企业出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。密码模式如图4所示。

图4  密码模式

1)用户向应用提供用户名和密码。

2)应用将用户名和密码发给认证服务器,向应用服务器请求令牌。

3)认证服务器确认无误后,向应用提供访问令牌。

(4)客户端应用模式

客户端应用模式(Client Credentials)是指应用程序以自己的名义,而不是以用户的名义,向“服务提供商”进行认证。在这种模式中,应用以自己的名义要求“服务提供商”提供服务,其实不存在授权问题。客户端应用模式如图5所示。

图5  客户端应用模式

1)应用向认证服务器进行身份认证,并要求一个访问令牌。

2)认证服务器确认无误后,向应用提供访问令牌。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-9-20 10:55 , Processed in 0.012934 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表