【问题标题】:Self submitting form in a node application在节点应用程序中自行提交表单
【发布时间】:2021-11-22 06:52:19
【问题描述】:

您好,我正在使用 node-oidc-provider 实现 SSO 客户端

背景:

node-oidc-provider 有一个内置的表单提交,要求用户通过单击一个按钮来“确认他想要退出”,该按钮提交一个隐藏的表单,该表单将撤销他的 OAuth 令牌。

我想通过在页面加载时自行提交表单来跳过确认步骤,就像包作者建议的here

问题:

我在脚本和元标记中添加了一个随机数,但浏览器仍然拒绝加载我的脚本

async function getNonce () {
  const crypto = require("crypto");
  return crypto.randomBytes(16).toString("base64");
}

async function logoutSource (ctx, form) {
  // @param ctx - koa request context

 const nonce = await getNonce();

 ctx.body = `<!DOCTYPE HTML>
   <head>
     <title>Logout</title>
     <meta http-equiv="content-security-policy"
      content="
        script-src 'nonce-${nonce}' strict-dynamic 'unsafe-inline';
        default-src 'self';
     ">
   </head>
   <body>
     ${form}
     <script nonce="${nonce}">
       var form = document.forms[0];
       var input = document.createElement('input');
       input.type = 'hidden';
       input.name = 'logout';
       input.value = 'yes';

       form.appendChild(input);
       form.submit();
     </script>
   </body>
 </html>`;

查看浏览器网络选项卡中的请求,我看到了随机数

但是,当浏览器呈现响应时,nonce 会以违反 CSP 为由被剥离,我猜测元头有问题,但在阅读 CSP 文档后我无法找出错误

更新 1 Chrome 显示此错误消息

火狐:Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”).

【问题讨论】:

  • 'strict-dynamic' 应该是单引号。现代浏览器从标签中隐藏了'nonce' 的值,以避免随机数泄露和重用。而且您没有显示 CSP 违规消息,这有助于找出导致错误的原因。
  • 谢谢,我已经添加了缺少的引号并用错误消息更新了帖子,感觉太笼统了,我什至没有考虑在这里添加它
  • inline script 可以是&lt;script&gt; 标签或&lt;tag onclick=''&gt;&lt;a href='javascript:...'&gt;。最后两个无法使用nonce 解决。您可以通过 CSP 报告找出导致此违规的确切原因(您需要将 report-sample 令牌添加到 script-src 指令并使用 report-uri 指令)。但据推测,违规代码的片段位于第 13 行的 /ads/session/end 文件中。
  • 啊我不知道report-sample 一直想知道为什么没有更清晰的错误消息,因为浏览器确切地知道它拒绝运行我的脚本的原因!第 13 行,您可以在上面的网络选项卡图像中看到,它是我的脚本标签的开头
  • 我猜错误消息是故意留下的通用

标签: node.js browser content-security-policy


【解决方案1】:

您似乎同时发布了两个 CSP - 第一个通过 HTTP 标头,第二个通过元标记。
在这种情况下,所有源都应通过两个未划伤的 CSP 才能被允许,但第一个 CSP 没有 nonce
推测第一个 CSP 是由 Helmet 中间件发布的默认 CSP,它在 NodeJS 的依赖项中。

查看HTTP响应头,手册为here

如果存在Content-Security-Policy HTTP 标头,您有 2 个选择:

  • nonce 添加到HTTP 标头中并删除元标记CSP。
  • 在 HTTP 标头中禁用 CSP 并使用元标记。

如果这是 Helmet 的技巧,那么可以使用以下方法关闭 CSP:

// This disables the `contentSecurityPolicy` middleware but keeps the rest.
app.use(
  helmet({
    contentSecurityPolicy: false,
  })
);

【讨论】:

  • 是的,这正是这里发生的事情!你刚刚拯救了我的理智,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-19
  • 1970-01-01
  • 1970-01-01
  • 2016-05-09
相关资源
最近更新 更多