gpt4 book ai didi

javascript - 使用 CSP 的 nonce 策略响应 *.js.erb

转载 作者:行者123 更新时间:2023-12-05 00:26:57 24 4
gpt4 key购买 nike

我正在使用 rails 5.2.1 内容安全策略 DSL 实现 CSP。我的策略设置为:

Rails.application.config.content_security_policy do |policy|
policy.default_src :self, :https
policy.connect_src :self
#...
policy.script_src :self
end

# If you are using UJS then enable automatic nonce generation
Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }

我也有 <%= csp_meta_tag %>在我的 application.html.erb
此时我需要添加一个 nonce: true标记到任何内联脚本以使它们满足策略。我已经做到了,它按预期工作。但是,我无法维护现有的 AJAX 样式功能。例如,我有类似的东西(注意 remote: true ):
# index.html.erb
<%= link_to create_object_path, id: "#{object.code}",method: :post, remote: true do %>
<button type="button">Create object</button>
<% end %>

在我的 Controller 中
def create
@object = current_user.object.create
respond_to do |format|
if @object
format.js
else
redirect_back
format.html
end
end
end

在我的 *.js.erb文件
$("#<%= @object.service.id %>").text("Added!");

对象已成功创建,但我认为该策略阻止了上述 "Added"我添加到 DOM 的成功消息。我没有在控制台中看到任何错误,所以我不确定从这里去哪里。

我在这种情况下的理解是脚本标签临时插入 *.js.erb 的内容。文件和这些脚本标签不包含随机数。或者,它是不匹配的。

我一直坚持如何从这里进行故障排除。即使向客户端发送数据的不同架构模式是前进的方向,这里的任何指导都非常感谢。提前致谢。

最佳答案

我遇到了类似的问题。在我的例子中,它并没有拒绝运行 js.erb 文件本身,而是通过使用 render 来拒绝运行嵌套在该文件中的模板中的脚本。 .因此,此答案可能对您的具体情况有有限的实用性。也就是说,我确实尝试使用 Rails 6.1.1 版重现您的问题,但不能。
但是,即使您克服了仅运行 .js.erb 文件的初始障碍,您仍然会遇到嵌套脚本的问题:如果您的 .js.erb 文件 render s 包含 script 的模板标签。该脚本不会运行,因为它源自的请求为其分配了一个新的随机数,该随机数与元标记中的随机数不匹配。
因此,对于那些像我一样从搜索引擎来到这里的人来说,这是我追求的一般策略,以使异步嵌入式 JS 与 CSP 一起用于该嵌套案例并假设 .js.erb 文件本身运行。以您的案例为例:

  • 在 AJAX 请求中发送随机数。我想你不会绕过编写一些自定义 JS 来发送请求。就像是:
    document.getElementById('<%= object.code %>').addEventListener('click', e => {
    e.preventDefault(); // So we don't send two requests

    fetch('<%= create_object_path %>', {
    method: 'POST',
    headers: {
    'Content-Type': 'application/json;charset=utf-8'
    },
    body: JSON.stringify({
    nonce: document.getElementsByName('csp-nonce')[0].content
    })
    });
    });
    这会将来自元标记的随机数以 nonce 的形式发送到服务器。范围。
    您可能需要删除 remote: true从你的链接这个工作。当然,这个脚本本身需要是“nonced”,否则它不会运行!
  • 将随机数分配给 @nonce Controller 中的实例变量:
    @nonce = params[:nonce]
  • 无论您在哪里渲染脚本,请执行以下操作:
    <%= javascript_tag nonce: @nonce || true do %>
    ...

  • 对于那些想知道如何使用现有异步表单的人:
  • 添加此表单域:<%= hidden_field_tag :nonce %>
  • 在表单提交时,将元标记中的随机数分配给隐藏字段:
    document.getElementById('id_of_submit_button').addEventListener('click', async e => {
    document.getElementById('nonce').value = document.getElementsByName('csp-nonce')[0].content;
    });
    在这种情况下,您不想阻止事件的默认行为,因为您希望提交表单。

  • 然后继续上面的步骤 2(将 nonce 分配给 Controller 实例变量)。
    我希望作为一般策略,这对某些人有用。我希望它可以作为如何让 .js.erb 文件本身运行的灵感。
    更新:当然,对于您的特定(但有限)用例,您可以简单地将对象的服务 ID 作为您返回给客户端的一些 JSON 对象的一部分返回,而不是呈现 .js.erb 模板。我说“有限”是因为这不适用于真正需要渲染模板的人。
    如果你确实想渲染你的 .js.erb 文件,我怀疑像 this 这样的东西也适用于您的情况,而不是检查 HTTP_TURBOLINKS_REFERRER header 存在,您检查 request.xhr? .只知道 starting in newer Rails versions , remote: true没有为 request.xhr? 设置必要的 header 工作了。但由于您使用的是 5.2.1,它可能对您有用。

    关于javascript - 使用 CSP 的 nonce 策略响应 *.js.erb,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54017005/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com