ChatGPT解决这个技术问题 Extra ChatGPT

如何保护 REST API 调用?

我正在开发一个在后端使用一些流行的 web 框架的 restful web 应用程序,比如(rails、sinatra、flask、express.js)。理想情况下,我想用 Backbone.js 开发客户端。如何只让我的 javascript 客户端与这些 API 调用交互?我不希望这些 API 调用公开并由 curl 调用,或者只是通过在浏览器上输入链接来调用。

您的所有 API 调用是否都需要在提供页面时传递给客户端的令牌?
Amazon AWS javascript SDK 使用预签名对象 URL:- docs.aws.amazon.com/AmazonS3/latest/dev/…

C
Community

作为第一个原则,如果你的 API 被你的 JS 客户端使用,你必须假设它是公开的:一个简单的 JS 调试器将攻击者置于一个位置,在那里他可以从他选择的工具。

也就是说,如果我正确阅读了您的问题,这不是您想要避免的:您真正不希望发生的是,您的 API 被使用(定期)而没有涉及您的 JS 客户端。以下是一些关于如果不强制执行的想法,那么至少鼓励使用您的客户端:

我敢肯定,您的 API 有某种身份验证字段(例如在客户端计算的哈希)。如果没有,请查看 This SO question。确保使用基于会话(aot 硬编码)提供给 JS 客户端的盐(甚至 API 密钥)。这样一来,未经授权的 API 使用者就会被迫做更多的工作。

在加载 JS 客户端时,请记住一些 HTTP 标头(想到用户代理)和 IP 地址,并在它们发生变化时要求重新验证,为通常的嫌疑人使用黑名单。这迫使攻击者再次更彻底地完成作业。

在服务器端,记住最后几个 API 调用,在允许另一个 API 调用之前,检查业务逻辑现在是否允许新的调用:这使攻击者无法将他的许多会话集中到与您的服务器的一个会话中:结合其他措施,这将使施虐者很容易被发现。

我可能没有说得那么清楚:我认为不可能让施虐者完全不可能消费你的服务,但你可以让它变得如此困难,这可能不值得麻烦。


这是有用的信息,但是如果我想从我的后端 api 到另一个 api 应用程序(如单独的服务器)进行一些身份验证,为了简化我的问题,我希望我的后端又名 node.js 将获取请求发送到另一个后端 -端服务器是我自己的,出于某些原因,这是需要的,但我想保护 api 调用,因为它可以访问敏感数据,而且我不能使用 sesions 或 jwt,因为我不能将它们实际存储在浏览器中。
@Thepyramid API调用在服务器端做什么都没关系,特别是如果服务器端进行另一个2nd-ĺevel API调用。重要的部分是不要将您的服务器视为代理,而是将其视为应用程序。
你能解释一下如何制作应用程序而不是代理吗
我的意思是:要获得相当大的安全性,您需要使用 Web 应用程序具有的所有工具:会话、身份验证数据库、业务逻辑。如果不这样做并且只是将您的服务器视为将请求传递给另一台服务器的一种方式,那么您只是将其用作该另一台服务器的代理,并且受到其他服务器提供的任何安全性的限制。
@PirateApp 攻击者可以轻松地忽略 CSRF 标头。它们仅在终端设备是未打补丁的浏览器时才有效
g
gview

您应该实施某种身份验证系统。处理此问题的一种好方法是定义一些预期的标头变量。例如,您可以有一个返回会话令牌的 auth/login API 调用。对您的 API 的后续调用将期望在 HTTP 标头变量中设置一个会话令牌,该变量具有特定名称,例如“your-api-token”。

或者,许多系统使用某种 api 帐户系统创建预期的访问令牌或密钥(如 youtube、facebook 或 twitter)。在这些情况下,您的客户必须以某种方式将这些存储在客户端中。

然后只需将会话检查添加到您的 REST 框架并引发异常即可。如果可能的话,状态码(要安静)将是 401 错误。


尽管没有什么能阻止他们查看标题并复制它们。
@cdmckay - 令牌必须与会话中存储的令牌匹配。如果它来自不同的会话,简单地复制标题将导致“未经授权”响应。
他们仍然可以使用相同的会话并在将请求发送到 API 之前更改请求......或者甚至在运行时使用控制台生成一个调用,其中匹配的标题/字段只修改您需要的部分......
@PotterRafed:如果用户访问他或她自己的有效会话,则称为使用应用程序调用,而不是攻击它。身份验证的目的是防止访问其他用户的会话/数据。
@AndreiVolgin 是的,很公平,但这仍然是一个漏洞
b
bbozo

现在有一个开放标准称为“JSON Web Token”,

https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token

JSON Web Token (JWT) 是一种基于 JSON 的开放标准 (RFC 7519),用于创建声明一些声明的令牌。例如,服务器可以生成具有“以管理员身份登录”声明的令牌并将其提供给客户端。然后,客户端可以使用该令牌来证明他们以管理员身份登录。令牌由服务器的密钥签名,因此服务器能够验证令牌是否合法。这些令牌被设计为紧凑、URL 安全和可用,尤其是在 Web 浏览器单点登录 (SSO) 上下文中。 JWT 声明通常可用于在身份提供者和服务提供者之间传递经过身份验证的用户的身份,或业务流程所需的任何其他类型的声明。[1][2]令牌也可以进行身份验证和加密。[3][4]


什么会阻止用户复制他们的令牌并在任何其他响应中使用它?
@UladKasach 老实说,我从来没有真正深入研究过它们,但是 afaik 它们是可过期的,对您的用户来说是独一无二的,并且由 SSL 加密(您当然正在练习),这与 oauth afaik 背后的想法完全相同
A
Alex from Jitbit

当客户端首次加载您的 index.html(或骨干网.js 等)时,在服务器上设置一个 SESSION var。在每次 API 调用时在服务器端检查这个 var。

PS这不是一个“安全”解决方案!!!这只是为了减轻服务器上的负载,这样人们就不会滥用它或从其他网站和应用程序“热链接”您的 API。


C
Community

对不起@MarkAmery 和 Eugene,但这是不正确的。

您在浏览器中运行的 js+html(客户端)应用程序可以设置为排除对 API 的未经授权的直接调用,如下所示:

第一步:设置 API 以要求身份验证。客户端必须首先通过服务器(或其他一些安全服务器)对自己进行身份验证,例如要求人类用户提供正确的密码。在进行身份验证之前,不接受对 API 的调用。

在身份验证期间,会返回一个“令牌”。

身份验证后,仅接受带有身份验证“令牌”的 API 调用。

当然在这个阶段只有拥有密码的授权用户才能访问API,尽管如果他们是调试应用程序的程序员,他们可以直接访问它进行测试。

第二步:现在设置一个额外的安全 API,在客户端 js+html 应用程序最初从服务器请求后的短时间内调用。这个“回调”会告诉服务器客户端下载成功。仅当最近成功请求客户端时才限制您的 REST API 调用。

现在,为了使用您的 API,他们必须首先下载客户端并在浏览器中实际运行它。只有在成功接收到回调,并在短时间内用户进入后,API才会接受调用。

因此,您不必担心这可能是没有凭据的未经授权的用户。

(问题的标题是“我如何保护 REST API 调用”,从你所说的大部分内容来看,这是你主要关心的问题,而不是如何调用你的 API 的字面问题,而是由谁来调用,对吗? )


第二点没有意义。如果攻击者需要加载您的应用程序,他会这样做(您的回调是可见的)。然后攻击。
第 2 点是第 1 点的补充。攻击者仍然需要身份验证。第 2 点仅增加了实际下载 html 应用程序以获得授权的需要。因此,在没有应用程序的情况下直接调用 API(大概只有在身份验证后才能访问和下载)是不可能的。这是这个问题所要求的。
您可以只允许来自您的域的请求。
这只限制了对域内的调用,所以现在 javascript 浏览器应用程序用户必须在域内(可能不是 knd 想要的),并且这些用户仍然可以通过 curl 直接调用 API。
您似乎忽略的是,无论您要求用户的浏览器做什么,都可以被攻击者复制 - 要让浏览器做到这一点,它必须是可读的。
P
Pavneet Singh

这就是我所做的:

使用诸如 X-APITOKEN 之类的调用使用 HTTP 标头保护 API:在 PHP 中使用会话变量。有一个登录系统并将用户令牌保存在会话变量中。使用 Ajax 调用 JS 代码到 PHP 并使用带有 curl 的 session 变量调用 API。这样,如果会话变量未设置,它将不会调用并且 PHP 代码包含 API 的访问令牌。