Chrome declarativeNetRequest.updateDynamicRules – response headers modification breaks other not related webapps

huangapple go评论141阅读模式
英文:

Chrome declarativeNetRequest.updateDynamicRules - response headers modification breaks other not related webapps

问题

我试图在我的Chrome扩展程序中为一些请求添加响应头。虽然它对我正在处理的网站按预期工作,但它破坏了一些在清单中甚至未指定的其他Web应用程序。我注意到,这些应用程序正在使用单点登录(SSO)身份验证,并且它在加载页面时破坏了它们。

其中一个例子:
在初始加载期间,一个Web应用程序(ASP.NET仪表板)正在加载一些资源(页面本身、脚本、一些JSON文件),然后它正在对https://dc.services.visualstudio.com/v2/track进行API调用。我比较了这之前的所有调用 - 都看起来一样,这是唯一一个如果我安装了扩展程序就会失败的调用。
如果我移除扩展程序 - 一切都正常,应用程序正在加载并显示仪表板。
我还注意到,这个API调用与没有安装扩展程序的工作情景中的API调用不完全相同。它缺少许多标头(7个对比21个),而且甚至没有显示它是预检还是实际的POST请求。

我花了很多时间尝试调试并查看出了什么问题,但迄今为止没有运气。

这是我的配置

manifest.json

{
  ...
  "permissions": [
    "webRequest",
    "notifications",
    "storage",
    "tabs",
    "activeTab",
    "cookies",
    "scripting",
    "declarativeNetRequest"
  ],
  "host_permissions": [
    "*://somedomain.com/*"
  ],
  "background": {
    "service_worker": "background.js",
    "type": "module"
  }
}

background.js

...
chrome.declarativeNetRequest.updateDynamicRules({
  removeRuleIds: [123456],
  addRules: [{
    id: 123456,
    priority: 1,
    condition: {
      regexFilter: 'https://somedomain.com', // 也尝试了urlFilter
      domains: ['somedomain.com'],
      resourceTypes: [
        chrome.declarativeNetRequest.ResourceType.MAIN_FRAME
      ]
    },
    action: {
      type: chrome.declarativeNetRequest.RuleActionType.MODIFY_HEADERS,
      responseHeaders: [
        {
          header: 'foo',
          operation: chrome.declarativeNetRequest.HeaderOperation.SET,
          value: 'bar'
        }
      ]
    }
  }]
})

如您所见 - 我在这里设置了一个自定义标头(只是作为示例)。真正的目的是修改Content-Security-Policy标头。无论我触碰或添加什么标头 - 结果总是相同的。
如果在background.js的responseHeaders设置中提供一个空数组 - 一切正常。如果该数组中有条目,它就会开始失败。

chrome.declarativeNetRequest.getDynamicRules()仅返回我创建的规则 - 没有其他规则。

我还尝试在manifest.json中添加类似的静态规则。它得到了相同的结果。

任何想法都将不胜感激。

英文:

I'm trying to add a response header to some requests using my chrome extension. While it works as expected for the website I'm trying to deal with, it breaks some other web applications not even specified in the manifest. I noticed, those apps are using SSO authentication and it breaks them while it loads the page.

One of the examples:
During initial load a webapp (ASP.NET dashboard) is loading some resources (page itself, scripts, some json file) and then it's making an API call to https://dc.services.visualstudio.com/v2/track. I compared all calls up until this one - all look the same, and this is the first one that fails if I have my extension installed.
If I remove the extension - everything works fine, app is loading and showing the dashboard.
I also noticed that this API call is not exactly the same as the one from working scenario (without extension installed). It's missing a lot of headers (7 vs 21), and it's not even showing if it's a preflight or actual POST request.

I spent a lot of time trying to debug and see what's wrong, but no luck so far.

Here is my config

manifest.json

{
  ...
  "permissions": [
    "webRequest",
    "notifications",
    "storage",
    "tabs",
    "activeTab",
    "cookies",
    "scripting",
    "declarativeNetRequest"
  ],
  "host_permissions": [
    "*://somedomain.com/*"
  ],
  "background": {
    "service_worker": "background.js",
    "type": "module"
  }
}

background.js

...
chrome.declarativeNetRequest.updateDynamicRules({
  removeRuleIds: [123456],
  addRules: [{
    id: 123456,
    priority: 1,
    condition: {
      regexFilter: 'https://somedomain.com', // tried urlFilter too
      domains: ['somedomain.com'],
      resourceTypes: [
        chrome.declarativeNetRequest.ResourceType.MAIN_FRAME
      ]
    },
    action: {
      type: chrome.declarativeNetRequest.RuleActionType.MODIFY_HEADERS,
      responseHeaders: [
        {
          header: 'foo',
          operation: chrome.declarativeNetRequest.HeaderOperation.SET,
          value: 'bar'
        }
      ]
    }
  }]
})

As you see - I'm setting a custom header here (just for an example). Real intention is to modify Content-Security-Policy header. No matter what header I'm touching or adding - the result is always the same.
If I provide an empty array in responseHeaders setting in background.js - everything works. It starts failing if there is an entry in that array.

chrome.declarativeNetRequest.getDynamicRules() returns only the rule I've created - no other rules.

I also tried to add a similar static rule to manifest.json. It gives the same result.

Any ideas would be much appreciated.

答案1

得分: 1

感谢 @wOxxOm 提供了正确的方向。
这确实是 Chromium 中的一个错误 - https://bugs.chromium.org/p/chromium/issues/detail?id=1468558

我使用了该错误页面上的一个建议,并在我的代码中添加了一个解决方法,效果很好。

解决方法是在 background.js 中添加一个虚拟监听器:

chrome.webRequest.onBeforeSendHeaders.addListener(
  () => {},
  { urls: ['<all_urls>'] },
  ['requestHeaders', 'extraHeaders'],
);

我还必须像这样修改 manifest.json 中的 host_permissions:

"host_permissions": ["<all_urls>"]
英文:

Thanks @wOxxOm for a right direction.
This is indeed a bug in Chromium - https://bugs.chromium.org/p/chromium/issues/detail?id=1468558

I've used one of the suggestions from the bug page and added a workaround to my code, which worked well.

The workaround was to add a dummy listener to background.js:

chrome.webRequest.onBeforeSendHeaders.addListener(
  () =&gt; {},
  { urls: [&#39;&lt;all_urls&gt;&#39;] },
  [&#39;requestHeaders&#39;, &#39;extraHeaders&#39;],
);

I also had to modify host_permissions in manifest.json like this:

&quot;host_permissions&quot;: [&quot;&lt;all_urls&gt;&quot;]

huangapple
  • 本文由 发表于 2023年8月10日 23:28:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76877210.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定