fix: 处理 Copilot 二轮 review 的 10 条评论
- BrowserView: 即使 host 在白名单,GUI 自身 origin 永不给 allow-same-origin(裸 host 条目覆盖所有端口时可提权) - intercept: revealInExplorer 相对路径经 resolveSidebarPath 解析后再 revealPaths(交付物路径是相对的) - intercept: ctx.betterSidebar 改为 ctx.get(#357 纤维链读取约定) - FileTree/EditorHost/TreePanel/tabs: 把 revealed 贯通到树行渲染 + 高亮类 + scrollIntoView(此前高亮永不渲染) - state.revealPaths: 重建祖先目录时保留前导分隔符(POSIX/UNC 此前目录永远折叠) - state.schedulePersist: 仅活动会话写入全局宽度(targeted open 不再用非活动会话的过期宽度覆盖拖拽值) - browser.probe: GET 回退显式取消 body(否则流式/大响应挂住 socket) - terminal-font: leading generic 前只放 symbols-only 字体;fully-patched 放 generic 后(避免 hijack 度量字体) - sidebar.module.css: 恢复拖拽反馈(#130 的 silent resize 与 PR 描述冲突,取 HEAD) - Sidebar: 剩余 4 处 ctx.betterSidebar 改 ctx.get - tests: 补 revealPaths/iframeSandboxFor/terminal-font 回归测试 + EditorHost/FileTree 测试补 revealed prop
This commit is contained in:
@@ -55,9 +55,25 @@ const BROWSER_IFRAME_SANDBOX_SAME_ORIGIN =
|
||||
* the page access to the GUI — it stays cross-origin to it and to every
|
||||
* other site — but it does give it its OWN origin privileges (localStorage,
|
||||
* fetch without CORS), so it is only granted for the explicit allowlist.
|
||||
*
|
||||
* The GUI itself is the one hard exception: even when its own host is
|
||||
* allowlisted (a bare-host entry covers every port, so the GUI origin
|
||||
* matches), a page at the GUI's exact origin must never get
|
||||
* `allow-same-origin` — that would make it same-origin with its parent and
|
||||
* hand it the GUI's storage/API (and the ability to shed the sandbox). The
|
||||
* GUI keeps the opaque-origin sandbox no matter what the allowlist says.
|
||||
*/
|
||||
export function iframeSandboxFor(url: string | undefined, allowedLoopback: string): string | undefined {
|
||||
export function iframeSandboxFor(url: string | undefined, allowedLoopback: string, selfOrigin?: string): string | undefined {
|
||||
if (url === undefined) return undefined
|
||||
if (selfOrigin !== undefined) {
|
||||
let parsed: URL
|
||||
try {
|
||||
parsed = new URL(url)
|
||||
} catch {
|
||||
return BROWSER_IFRAME_SANDBOX
|
||||
}
|
||||
if (parsed.origin === selfOrigin) return BROWSER_IFRAME_SANDBOX
|
||||
}
|
||||
return isAllowedLoopbackUrl(url, allowedLoopback)
|
||||
? BROWSER_IFRAME_SANDBOX_SAME_ORIGIN
|
||||
: BROWSER_IFRAME_SANDBOX
|
||||
@@ -230,7 +246,7 @@ export function BrowserView(props: TabComponentProps) {
|
||||
key={`${reloadKey}:${noSandbox ? 'ns' : 'sb'}`}
|
||||
className={css.browserFrame}
|
||||
src={url}
|
||||
sandbox={noSandbox ? undefined : iframeSandboxFor(url, store.getPrefs().browserAllowedLoopback)}
|
||||
sandbox={noSandbox ? undefined : iframeSandboxFor(url, store.getPrefs().browserAllowedLoopback, window.location.origin)}
|
||||
referrerPolicy="no-referrer"
|
||||
allow=""
|
||||
title={url}
|
||||
|
||||
Reference in New Issue
Block a user