如何保护自己的 iFrame 不让身份验证令牌被盗?

How to Secure own iFrame from having the auth Token stolen?

提问人:iheb salah 提问时间:10/30/2023 最后编辑:Brian Tompsett - 汤莱恩iheb salah 更新时间:10/31/2023 访问量:44

问:

我目前在为我的聊天机器人创建 iFrame 时遇到了问题。

情况如下。用户 A 想 www.websiteUserA.com 将我的聊天机器人嵌入到他的网站上。用户 A 在使用 Google Auth 访问 myapp.com 并安全登录时被我的后端识别。

现在的问题是,正在访问 www.websiteUserA.com 的用户 A 的客户也需要被标识为用户 A 的客户。为此,我想到引入一个 jwt,我可以使用设置声明,以后可以在发出请求时检查和验证这些声明。

现在的问题是,如果我以任何形式向前端公开令牌。任何人,即“黑客”,都可以识别为“用户A的客户”,理论上可以在自己的网站上使用聊天机器人,同时让用户A负责所有使用。

可悲的是,在任何情况下都不可能允许如此轻易的冒充。

为了解决这个问题,我想引入用户 A 可以设置的允许域。因此 www.websiteUserA.com 应该是唯一允许向我发送此 jwt 令牌的域。可悲的是,请求推荐很容易被欺骗。

另一种解决方案是可能只与用户 A 的后端通信。用户 A 将从我那里收到一个 API 密钥,该密钥负责管理和重新颁发这些 JWT 令牌。这将确保令牌永远不会到达前端。但是,由于可用于托管和管理 www.websiteUserA.com 的不同体系结构,因此设置可能非常不直观,更不用说用户 A 的后端服务器上处理所有这些请求的负载增加了。

我还想到了最后一个解决方案。这是在 flask 会话中包含 jwt 令牌(我使用 flask 作为我的 webAPP)。Flask 会话使用以下参数进行保护:

app = Flask(__name__)
csrf = CSRFProtect(app)
app.config['SECRET_KEY'] = SECRET_KEY

app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=30)
app.config['SESSION_COOKIE_SECURE'] = True
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'None'

目标是使提取 jwt 代币变得“更难”。这应该不是不可能,但这些参数将有助于保护令牌免受 JavaScript 和 XSS 攻击。

你能帮帮我吗?我不知道我应该如何保护我的应用程序,因为无论我选择哪种方法,我仍然发现自己很脆弱。谁能向我推荐更好的方法?大型科技公司是如何做到这一点的?我想谷歌、Facebook或任何其他大公司都会很容易地解决这个问题。

我只想提供尽可能安全可靠的服务,:D。

身份验证 安全 iframe Web 应用程序

评论

0赞 iheb salah 10/30/2023
我想到了另一个想法。我想也许我可以给用户 A 一个 API 密钥,它每 5 分钟左右从我的服务器获取一个新令牌。因此,黑客将不断竞相获得只能在短时间内使用的令牌。不确定黑客是否可以编写一些爬虫脚本,在每次制作新令牌时获取新令牌。

答:

0赞 Lajos Arpad 10/31/2023 #1

没有 100% 这样的东西。例如,如果用户从咖啡馆浏览并前往厕所,攻击者可能会模拟此用户。因此,没有完美的防御,我们需要对可能提出的任何解决方案持保留态度。

首先是:HTTPS。这样,出于安全考虑,您的请求将使用加密。因此,如果 JWT 是 POST 参数或 HTTPS 下的持有者令牌,那么您将拥有一定的安全性。

接下来,您可以将其设置为一次性令牌,而不是在每个请求时发送 JWT,也就是说,您将拥有尚未过期但已使用的 JWT 黑名单。这样,如果您的用户使用当时有效的 JWT 进行身份验证,那么通过使用该 JWT,JWT 将变得无效,如果攻击者甚至设法窃取它,它将不再有用。

当然,您将有一个实际的会话 ID,而不是 JWT,它将用作会话标识符,并且 JWT 将仅用于身份验证。

这种方法将使攻击者很难窃取 JWT,即使他/她设法这样做,也不会对他/她进行任何奖励,因为当他/她使用它时,JWT 已经无效。

JWT 通常包含到期日期,因此当有效的 JWT 用完时,您可以将其列入黑名单并使用 cron 作业定期从列入黑名单的 JWT 中删除过期的 JWT,以避免堆积过多有用的数据。

因为,如果你的 JWT 的生命周期为 4 小时,而你现在用完了它,你的 JWT 被列入黑名单,所以没有人会重复使用它,那么 4 小时后它可以从黑名单中删除,因为在这一点上,JWT 用完是无趣的,因为它无论如何都过期了。

评论

0赞 iheb salah 10/31/2023
感谢您的建议方法!我想我可能会尝试实现它。不过我还有 1 个问题。如何在不暴露前端任何机密的情况下安全地将这些 JWT 或会话 ID 提供给用户 A 的客户?也许后端到后端。用户 A 的服务器要求我的服务器使用 JWT 进行身份验证,我的服务器将向该 JWT 返回会话 ID,然后将会话 ID 传递到前端?
0赞 Lajos Arpad 10/31/2023
@ihebsalah你绝对可以在后端到后端进行,但你不应该害怕发布 JWT。毕竟,当您登录时,您还会发布敏感数据,最终会遇到同样的困境。幸运的是,HTTPS(安全超文本传输协议)会加密您的帖子参数,因此通过 HTTPS(而不是 HTTP)发布可以保护您传递的数据。是的,如果有人访问您的浏览器,那么他/她将访问您发送的敏感信息,但只要您不害怕发布用户名/密码,您也不必担心发布 JWT perse。
0赞 Lajos Arpad 10/31/2023
@ihebsalah为了保护智威汤逊,你只需要确保你确实使用了https,并且你的应用程序尽可能安全。保护它免受 XSS、SQL 注入、模板注入和其他安全问题的影响,你应该没问题。在这里阅读更多: linkedin.com/advice/0/... .如果这个答案帮助你了解如何解决你的问题,那么你可以考虑接受它作为正确答案。
0赞 iheb salah 10/31/2023
再次感谢兄弟:D。在这种情况下,用户 A 的 JWT 可以泄露吗?因为这毕竟是一个聊天机器人,可以向公众开放。公众是用户 A 的客户。如果这些客户之一要找到 JWT。然后将其发送到我服务器上的相应 api 端点;然后,他们将返回一个模拟用户 A 的会话 ID。
0赞 Lajos Arpad 10/31/2023
JWT 应与最终用户相关。因此,如果您有用户 A,而用户 A 有用户 A1、用户 A2、用户 A3、...轮到他,那么你的系统应该有一个 JWT 到 userA1, userA2, ...,即用户 A 的每个用户的 JWT。你也会将用户 A 嵌入到 JWT 中,所以 JWT 肯定属于你的明确客户,但同一个 JWT 也属于你的客户的用户。