✨ 增加 CSP 规则管理#1598
Draft
cyfung1031 wants to merge 8 commits into
Draft
Conversation
保存/启用/禁用/删除 CSP 规则时,若 chrome.runtime.sendMessage 的响应在 service worker 挂起后丢失(例如用户填写表单期间 SW 进入空闲),本地会把 这类"响应丢失"和服务端明确的失败混为一谈,直接提示保存失败——而实际上 突变已经在后台成功执行,用户重试时才会看到 revision 冲突,此时才发现 其实已经保存成功。现在 CspRuleClient 用 CspRuleAmbiguousResponseError 单独标记这种不确定情形,UI 侧据此重新拉取权威 state 校验 revision 是否 已推进,从而正确识别为成功或失败。 删除操作的确认气泡(Popconfirm)此前被嵌套在 DropdownMenuItem 内,与 Radix 的 DropdownMenu 共用可关闭层(dismissable layer)冲突,气泡在用 户尚未点到确认按钮前就随下拉菜单一起被关闭。现在删除改为复用本文件已有 的顶层 AlertDialog 确认模式(与"启用所有网站"确认一致),不再嵌套弹层。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist / 检查清单
背景
部分用户脚本在特定网站上会被 CSP response headers 阻止执行。ScriptCat 需要提供按网站管理的 CSP 规则,同时保留浏览器现有动态规则,并让高风险的全网站范围操作具备明确确认和可恢复的错误状态。
由于扩展使用 split incognito 模式,普通窗口和隐私窗口可能运行不同的 service worker。CSP 规则状态必须明确归属,不能依赖两个后台上下文之间的内存状态同步。
本次改动
csp_rule:state):incognito: "split",只在普通 service worker 注册 CSP rule handlers;隐私窗口显示普通窗口管理提示,不影响既有隐私窗口扩展页面流程。baseRevision;父级收到新快照后,旧表单仍使用打开时的 revision,冲突时刷新快照并关闭表单。tools文案,用户可见文本全部通过 i18n。实现考虑
1. CSP 状态只由普通 service worker 持有
Manifest 继续使用
incognito: "split",以兼容现有从隐私窗口打开确认页、安装页和其他扩展页面的流程。CSP service 通过
isCspRuleOwner(extensionEnv.inIncognitoContext)明确限制为普通上下文:这样不会通过全局切换到 spanning 模式改变既有隐私窗口行为,也不会让两个后台进程各自持有可互相覆盖的 CSP 内存状态。
2. revision 校验覆盖多个 service instance
每次 mutation 都会:
baseRevision;两个 service instance 共享 DAO 并竞争同一 revision 时,一个请求成功,另一个返回
revision_conflict,不会静默覆盖对方修改。3. 启动失败保持可恢复
无效 schema 或不支持的数据会先尝试移除旧的 CSP rule,但清理失败不会让 service 进入永久拒绝状态。
初始化错误会保留为可恢复状态,
retryApply可以重新初始化、重新清理并应用默认状态。storage read failure 也会明确返回错误,不会被当作缺少 state key。4. 表单与高风险操作保持一致
编辑表单使用打开时捕获的 revision,而不是父级后来收到的最新 revision。
编辑已有规则时 Enabled 状态只能通过列表中的单独操作改变;因此切换 All websites 时,确认条件始终基于真实规则的 enabled 状态。保存请求进行中锁定表单操作,避免双击产生第二个 mutation。
5. 保留可操作校验反馈
service 返回的
messageKey会透传到 UI,域名、规则数量、唯一域名数量和 patch 校验错误显示对应的本地化提示,而不是统一显示 storage error。已知限制
1. CSP 规则管理仅在普通窗口提供
隐私窗口不显示 CSP state 和编辑入口,用户需要从普通窗口管理规则。这样保留 split incognito 下现有扩展页面行为,并避免隐私与普通 service worker 之间出现无法原子协调的状态竞争。
2. 规则只移除 CSP response headers
当前规则类型固定为
removeCspHeaders,仅移除匹配响应中的 CSP headers,不会添加或修改用户自定义 CSP policy,也不会绕过其他浏览器安全机制。3. DNR 应用失败需要重试
state 会先持久化,再应用到 DNR。若浏览器拒绝或暂时无法更新动态规则,UI 会保留已保存 state 和失败 revision,并提供 Retry;受影响页面在应用成功前可能仍使用上一版本规则。
4. 域名范围和规则数量有限制
每条规则最多包含 100 个域名,全局最多包含 1,000 个唯一域名和 100 条规则。域名按 hostname 规范化,路径、凭据和通配符不会作为有效域名保存。
建议审查重点
revision_conflict;baseRevision;参考
docs/specs/csp-rule-management.mddocs/develop.mddocs/design.md验证
pnpm test:ci— 310 test files, 3297 tests passedpnpm lint:ci— Prettier, TypeScript, and ESLint passedpnpm build— passed (repository bundle-size/Monaco warnings only)