
如何获取文心一言 API Key 密钥(分步指南)
OWASP社区的主要目标之一是让开发者和技术人员意识到其应用程序和系统面临的安全风险。为此,社区发布了一些文档来强调最常见的安全问题。
其中,《OWASP十大安全风险》是最受欢迎的文档,主要关注Web开发领域。此外,还有一个专门针对API的文档:《API安全十大风险》。
在2019年和2023年的文档版本中,都将对象级授权失效(Broken Object Level Authorization,简称BOLA)列为最关键的安全风险。令人惊讶的是,尽管已经过去了四年,这一问题仍然在全球范围内影响着API的安全性。那么,有没有办法缓解甚至消除这个漏洞呢?
答案是肯定的:通过设计适当的授权系统,可以有效防止这一漏洞对API的影响。但在找到解决方案之前,我们需要先了解什么是对象级授权失效。
授权是确定用户可以访问哪些内容的过程。这种访问控制可以根据具体应用的业务规则以多种方式实现。
在API环境中,每个对受保护端点的请求都需要被分析,以确定客户端是否有权访问和执行请求的操作。通常,这种检查在代码层面完成,主要是验证客户端是否有权限访问API端点暴露的资源(对象)。
在某些场景中,需要保护的资源是API端点本身。例如,/profile
端点隐式返回当前用户的个人资料数据。API通常通过会话存储或请求中携带的访问令牌来识别当前用户。
而在其他场景中,需要保护的是请求的具体资源。例如,/profile/42
端点返回ID为42的用户个人资料数据。在这种情况下,仅仅比较当前用户ID和请求的用户ID可能是不够的。例如,管理员可能需要访问所有用户的个人资料数据。这时,授权检查应该验证当前用户是否有权访问请求的对象。
如果在使用对象ID的端点中进行不准确的权限检查,API可能会暴露在BOLA攻击的风险之下。攻击者可以通过操纵对象ID来访问他们无权访问的对象。
为了更好地理解对象级授权失效漏洞的危害,我们来看一个实际的例子。
假设你的银行提供了一个账户管理应用程序。作为开发者,你观察到应用程序通过调用https://thebankwebsite.com/accounts/9876543
端点来获取你的账户(账号9876543)数据。
你想起有位朋友也在同一家银行开户,并且你曾给他转过账。通过聊天记录,你找到了他的账号1029387。于是,你使用curl或其他HTTP客户端,将端点URL修改为https://thebankwebsite.com/accounts/1029387
,并重放HTTP请求到银行服务器。
令人惊讶的是,你竟然成功获取到了朋友的账户数据!这表明银行的API存在BOLA漏洞,其授权检查在对象访问层面失效了。
以下是该银行API可能的实现方式:
const express = require('express');
const app = express();
const { auth, requiredScopes } = require('express-oauth2-jwt-bearer');
// 验证访问令牌的有效性
const validateAccessToken = auth({
audience: '...yourApiIdentifier...',
issuerBaseURL: https://...yourDomain.../
,
});
// 检查访问令牌是否包含读取权限
const checkReadPermissions = requiredScopes('read:account');
app.get('/accounts/:accountNumber', validateAccessToken, checkReadPermissions, function(req, res) {
res.json(getAccountData(req.params.accountNumber));
});
这段Node.js代码展示了如何处理/accounts/:accountNumber
端点的GET请求。尽管该端点受两个中间件保护:
validateAccessToken
:确保客户端提供有效的访问令牌;checkReadPermissions
:确保访问令牌包含必要的read:account
权限范围;但这些检查并不足以实现对账户对象的精确访问控制,因此无法阻止用户访问其他账户的数据。
一种常见的建议是避免在端点URL中使用容易识别的对象标识符,例如银行账号。可以使用GUID(全局唯一标识符)代替银行账号,因为GUID是随机生成的值,难以被猜测。
然而,这种方法只能降低BOLA攻击的风险,并不能从根本上解决问题。如果攻击者能够找到对象ID与GUID之间的关联,这种保护机制就会失效。
真正的问题在于授权机制。API的访问控制不应仅限于控制对端点的访问,还需要验证只有授权用户才能访问端点暴露的对象。
例如,在银行账户的场景中,可以通过以下方式检查当前用户是否是账户的所有者:
app.get('/accounts/:accountNumber', validateAccessToken, checkReadPermissions, function(req, res) {
const userId = req.auth.payload.sub;
const account = getAccountData(req.params.accountNumber);
if (account.userId == userId) {
res.json(account);
} else {
res.status(403).json("Permission denied.");
}
});
虽然这种方法可以解决单一账户的授权问题,但对于更复杂的场景(如多人共有账户或银行员工访问权限)可能会显得力不从心。
为了应对复杂的授权需求,可以使用细粒度授权(Fine-Grained Authorization, FGA)。FGA通过分析各种属性和关系描述的上下文,来更精确地控制对资源的访问。
Auth0 FGA和OpenFGA通过集中管理授权逻辑,帮助开发者修复API中的对象级授权失效漏洞,同时保持代码清晰。
以下是银行账户场景的授权模型示例:
model schema 1.1
type user
type branch
relations
define employee: [user]
type account
relations
define branch: [branch]
define owner: [user]
define can_view: owner or employee from branch
通过FGA引擎,API可以根据授权模型和数据动态验证用户权限,从而避免BOLA漏洞。
本文详细介绍了对象级授权失效(BOLA)的概念及其危害,并通过实际案例分析了漏洞的成因。我们讨论了如何通过细粒度授权(FGA)解决这一问题,并展示了Auth0 FGA和OpenFGA的强大功能。
通过定义授权模型、存储授权数据以及在API中集成授权检查,开发者可以有效防止BOLA漏洞,同时保持代码的简洁和可维护性。
原文链接: https://auth0.com/blog/how-fine-grained-authorization-solves-critical-api-security-risk/