随着互联网的快速发展,应用程序接口(API)成为了不同系统和服务之间进行数据交换和通信的重要方式,然而API接口的广泛使用也引发了一系列的安全问题,在当今数字化时代,API接口安全问题的重要性不容忽视,恶意攻击者利用漏洞和不当的API实施,可能导致数据泄露、身份验证问题以及系统的完整性和可用性受到威胁,本文将探讨API接口安全问题的重要性并介绍常见的安全威胁和挑战,还将探讨如何保护API接口免受这些威胁并介绍一些最佳实践和安全措施
API(Application Programming Interface)是一组定义在软件系统之间进行交互的规则和约定,它允许不同的应用程序、服务或系统之间进行数据传输和功能调用以实现数据交换、共享资源和实现特定的业务逻辑,API接口通常以特定的协议进行通信,最常见的是基于HTTP(Hypertext Transfer Protocol)的REST(Representational State Transfer)和基于WebSocket的实时通信协议,RESTful API是一种基于资源的架构风格,通过HTTP请求方法(例如:GET、POST、PUT、DELETE)来执行操作并传输数据,它使用URL(Uniform Resource Locator)来标识和访问资源并使用HTTP状态码来表示操作的结果
API接口的工作流程可以描述为以下几个关键步骤:
常见的API接口类型有以下几种:
在测试API接口的安全性问题之前我们首先要做的就是发现接口,我们可以尝试访问如下常见的API文档接口进行检索:
/api
/swagger/index.html
/openapi.json
如果我们在测试过程中发现诸如"/api/swagger/v1/users/al1ex"的路径时我们可以通过向上进行遍历来尝试获取对应的接口文档路径:
/api/swagger/v1
/api/swagger
/api
下面我们使用portswigger的靶场对此来对隐藏的接口发现过程的一个示例,登录网站之后在我们重置密码的时候在BurpSuite中发现此时会调用API接口来发送密码重置的邮件信息
随后我们对上面可疑的接口进行检索测试,看看是否可以获取到API接口文档,随后直接移除后缀/winner,此时提示错误信息:{"error":"Malformed URL: expecting an identifier"}
紧接着我们再往上进行遍历移除/user,随后我们可以看到如下内容:
此时可以根据接口文档的说明来构造参数并对接口进行调用,实现问用户的删除操作:
在处理API请求时我们可以看到多种数据报文的请求格式,其中JSON格式是我们使用最多的,有时候我们其实也阔以尝试更改请求报文的格式进行一些其他的安全测试,例如:XML下的XXE漏洞风险点等,同时我们也可以考虑更改请求方法来进行不同的功能的测试,下面我们给出一个简易的报文格式更换示例:
首先在网站中访问产品并将其添加到购物车,此时会发现调用了"/api/products/1/price"接口
随后我们尝试调整请求方法将其更改为"OPTIONS"来检索该接口允许的方法,不同的方法其实有不同的功能,例如:DELETE(删除)、PUT(上传)等
随后我们将请求方法更改为PATCH并重新发送数据包,结果看到提示Content-Type非支持的类型
随后我们直接添加一个Content-Type头并将其赋值"application/json",同时在请求body中添加一个"{}",此时会得到如下回显,可以看到这里给出了参数提示
随后我们使用price参数并将其赋值为0,实现0元购物
有时候软件框架会自动将请求参数绑定到内部对象上的字段从而无意中创建隐藏的参数,在这个过程中我们可以通过手动检查API返回的对象来识别这些隐藏参数,例如: PATCH /api/users/请求允许用户更新用户名和电子邮件并包括以下JSON:
{
"username": "wiener",
"email": "wiener@example.com",
}
发送"GET /api/users/123"请求返回以下JSON:
{
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"isAdmin": "false"
}
从上面的结果中我们初步猜测此处的id与isAdmin存在某种绑定关系,要测试是否可以修改枚举的isAdmin参数值,我们可以将其添加到PATCH请求中
{
"username": "wiener",
"email": "wiener@example.com",
"isAdmin": false,
}
此外发送一个带有无效isAdmin参数值的PATCH请求:
{
"username": "wiener",
"email": "wiener@example.com",
"isAdmin": "foo",
}
如果应用程序的回显不同,这可能表明无效值会影响查询逻辑,但有效值不会,这可以指示用户可以成功地更新参数,然后我们可以发送一个将isAdmin参数值设置为true的PATCH请求以尝试利用该漏洞:
{
"username": "wiener",
"email": "wiener@example.com",
"isAdmin": true,
}
下面我们通过一个示例来进行演示说明:
我们登录网站后将商品加入购物车后点击支付的时候会发现此时没有足够的余额
随后我们在BurpSuite中捕获到如下请求记录:
从上面的报文中可以看到的是GET响应中的JSON结构包括一个chosen_discount参数,该参数不存在于POST请求中
右键单击"POST /api/checkout"请求并选择"Send to Repeater",随后在Repeater中将chosen_discount参数添加到请求中,回显结果如下所示:
随后我们将"percentage"更改为"x"并重新发送数据包,此时会收到如下错误提示,主要的原因是非数字的缘故
随后我们将chosen_discount百分比更改为100(打折),然后发送请求以解决问题
对于API接口的防御这里给出以下几点建议:
本篇文章对API接口的基本概念、工作流程、利用方式、防御措施进行了介绍,其中利用方式中的更改请求方法探测可用的方法类型并根据方法进行恶意利用、接口文档的检索方式、接口的隐藏参数的挖掘和利用等给出了示例,算是接口测试中的比较有意思和新颖的思路,在做接口的安全测试时不必过于局限越权、未授权之类的挖掘,扩展一下下思路