【问题标题】:How to prevent javascript from changing input value如何防止javascript更改输入值
【发布时间】:2016-03-11 08:30:42
【问题描述】:

我有一组隐藏的输入框,其中包含特别敏感的数据,点击一个按钮就可以将表单提交给第三方应用程序。

这些输入的值是在服务器端设置的。有这些输入的页面就是确认页面,用户点击按钮确认交易,隐藏的输入框内的数据就被贴出来了。

这本质上是非常不安全的,因为任何对 javascript 了解一半的人都可以加载 devtools 并使用 javascript 在提交数据之前更改隐藏输入的值。该页面甚至还方便地加载了 jQuery!哈! (我自己测试过)。

这是在具有有限用户集的私有应用程序上运行的,到目前为止还没有出现问题,但是现在需要在更公共的空间上使用相同的架构,并且交付它的安全隐患会有点吓人.

解决方案是在服务器端发布数据,但由于第三方应用程序的设置方式,服务器端发布不起作用(至少不是以直接的方式)。另一种方法是以某种方式阻止 javascript(当然还有扩展名 jQuery)更改输入框中的值。

我正在考虑实现(使用 setInterval)一个循环,该循环基本上检查输入值是否与原始值相同,如果不是,则将其改回,从而有效地防止值被更改。

我提出的方法会很容易被击败吗?也许有一种更优雅、更简单的方法来阻止 javascript 编辑那些特定的输入值?

** 编辑

对于任何沿着这条路来到这里的人:

经过多方面考虑,并且无法使用来自第三方应用程序的密钥对我的数据进行签名,我求助于从我的应用程序(ruby on rails 应用程序)手动发布数据服务器端。

在发布后显示正确的支付页面可能需要一些摆弄,我还没有测试过,但理论上这将是确保所有内容都提交服务器端并且用户永远不会有机会篡改它。

对于 Ruby on Rails 应用程序,this question 有一些很好的见解。

This answer 还展示了如何使用我在 cmets 中提到的 hacky 自动提交表单,但这可能容易出现与@dotnetom 回复的相同的漏洞。 (见 cmets)

再次感谢所有做出贡献的人。

【问题讨论】:

  • 我认为您提出的解决方案不会阻止任何人如果他们真的想更改值,即使它确实如此,理论上用户可以打开提琴手并编辑请求,或创建自定义请求在类似邮递员的地方。如果这些字段非常重要,您应该实施一些服务器端验证。
  • 是的,任何提议的方法都很容易被击败。您根本无法相信客户端值没有被操纵。
  • 没有办法保证这个安全。第三方服务需要有一些签名字段,依赖于所有提交的值,只有签名和值都有效时才处理请求
  • 使用 Escape ex。 javascript escape() 或加密你的信息
  • 客户端验证只是为了让用户觉得漂亮,停止他们需要的 AJAX 或回发来查看其是否有效。服务器端验证也应该用于防止任何讨厌的人乱搞东西。客户端上没有什么是安全的,一切都可以以某种形式进行操作。

标签: javascript jquery html ruby-on-rails


【解决方案1】:

您基于 setInterval 和其他 javascript 函数的解决方案将不起作用。拥有开发工具的人可以轻松地从控制台禁用它。如果无法从服务器发送这些参数,我看到的唯一选择是使用需要发送的所有参数的一些公钥生成签名。第三方应用程序可以验证此签名并检查参数是否真实。

但同样,如果您无法控制第三方应用程序,这是不可能的..

查看来自 twitter 的示例:https://dev.twitter.com/oauth/overview/creating-signatures

【讨论】:

  • 会接受这个答案,因为它与我从所有 cmets 得到的反馈相同。
【解决方案2】:

如果有人想更改这些输入字段的值,他们可以禁用 JS(这样可以绕过您的检查算法)并更新 HTML 中的输入值。

例如,这可以通过 FireBug 轻松完成。无需 JS。

如果涉及敏感数据,可能无法绕过服务器端发布或至少服务器端验证。

【讨论】:

  • 怎么样,获取要提交的表单并在服务器端验证,然后让服务器使用表单呈现中间页面并在加载时自动提交表单?理论上,该页面只会暂时呈现,因为提交重定向到第三方服务器上的页面。这样,就没有时间编辑发送的请求。你怎么看?
  • 据我了解,用户应该使用隐藏数据在页面上确认交易。如果表单是自动提交的,则用户无需进行确认。
  • 在用户确认后,自动提交将发生在支付页面之后的单独页面上。
【解决方案3】:

我正在考虑实现(使用 setInterval)一个循环 基本上检查输入值是否与原始值相同, 如果没有,请将其改回,有效地防止值 正在改变。

攻击者可以轻松克服这一点

  • 覆盖执行此定期检查的方法。检查这个solution
  • 设置可以在 setInterval() 更改后更改值的浏览器扩展
  • 禁用 JS。

基本上客户端验证只是为了确保可以避免服务器端调用以减少网络旅行,它不能成为保护数据完整性的最终边界。它只能在服务器端完成,这是一个用户无法操作的环境。

【讨论】:

  • 怎么样,获取要提交的表单并在服务器端验证,然后让服务器使用表单呈现中间页面并在加载时自动提交表单?理论上,该页面只会暂时呈现,因为提交重定向到第三方服务器上的页面。这样,就没有时间编辑发送的请求。你怎么看?
  • @MartinNyaga 它如何解决您的问题?用户仍然可以在表单未提交时对其进行编辑。
【解决方案4】:

我知道这是一篇较旧的帖子,但它激起了我的兴趣,因为与 javascript 安全性相关(但不相同)问题。

只考虑 OP 解决方案的逻辑,并假设我理解正确......

服务器设置 vals,用户确认,确认发送给第 3 方。问题是 vals 可以在发布到第 3 方之前进行编辑。

在这种情况下,可能的可行解决方案是;

  1. 使用唯一 ID 将 val 存储在原始服务器上
  2. 将确认发送回源服务器进行验证
  3. 如果验证 = true,则源服务器将转发给第 3 方

如果第 3 方需要将数据发回给用户,并且无法让服务器充当中间人(确实应该这样做),那么您就有点妥协了。

您仍然可以使用 AJAX 类型的 true fale 响应将数据发送回原始服务器给用户。

显然,恶意用户可以使用 javascript 编辑拦截 AJAX 响应,但是(假设第 3 方应用正在寻找某种用户 ID),您会将该 ID 标记为无效并在 AJAX 之前提醒第 3 方应用响应被传递给用户。

otoh,除了隐藏的输入框,更大的考虑应该是客户端 javascript 本身的操作。

任何敏感函数或变量都应该有一个验证包装器,以确保它们没有被修改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 2019-05-13
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    • 2017-04-30
    • 2014-08-03
    相关资源
    最近更新 更多