mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-04-25 11:18:22 +00:00
fix(frontend): resolve invalid HTML nesting and tabnabbing vulnerabilities (#1904)
* fix(frontend): resolve invalid HTML nesting and tabnabbing vulnerabilities Fix `<button>` inside `<a>` invalid HTML in artifact components and add missing `noopener,noreferrer` to `window.open` calls to prevent reverse tabnabbing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(frontend): address Copilot review on tabnabbing and double-tab-open Remove redundant parent onClick on web_fetch ChainOfThoughtStep to prevent opening two tabs on link click, and explicitly null out window.opener after window.open() for defensive tabnabbing hardening. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2d068cc075
commit
3acdf79beb
@ -188,17 +188,19 @@ export function ArtifactFileDetail({
|
||||
</Tooltip>
|
||||
)}
|
||||
{!isWriteFile && (
|
||||
<a
|
||||
href={urlOfArtifact({ filepath, threadId })}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<ArtifactAction
|
||||
icon={SquareArrowOutUpRightIcon}
|
||||
label={t.common.openInNewWindow}
|
||||
tooltip={t.common.openInNewWindow}
|
||||
/>
|
||||
</a>
|
||||
<ArtifactAction
|
||||
icon={SquareArrowOutUpRightIcon}
|
||||
label={t.common.openInNewWindow}
|
||||
tooltip={t.common.openInNewWindow}
|
||||
onClick={() => {
|
||||
const w = window.open(
|
||||
urlOfArtifact({ filepath, threadId }),
|
||||
"_blank",
|
||||
"noopener,noreferrer",
|
||||
);
|
||||
if (w) w.opener = null;
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{isCodeFile && (
|
||||
<ArtifactAction
|
||||
@ -218,17 +220,19 @@ export function ArtifactFileDetail({
|
||||
/>
|
||||
)}
|
||||
{!isWriteFile && (
|
||||
<a
|
||||
href={urlOfArtifact({ filepath, threadId, download: true })}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<ArtifactAction
|
||||
icon={DownloadIcon}
|
||||
label={t.common.download}
|
||||
tooltip={t.common.download}
|
||||
/>
|
||||
</a>
|
||||
<ArtifactAction
|
||||
icon={DownloadIcon}
|
||||
label={t.common.download}
|
||||
tooltip={t.common.download}
|
||||
onClick={() => {
|
||||
const w = window.open(
|
||||
urlOfArtifact({ filepath, threadId, download: true }),
|
||||
"_blank",
|
||||
"noopener,noreferrer",
|
||||
);
|
||||
if (w) w.opener = null;
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<ArtifactAction
|
||||
icon={XIcon}
|
||||
|
||||
@ -104,21 +104,21 @@ export function ArtifactFileList({
|
||||
{t.common.install}
|
||||
</Button>
|
||||
)}
|
||||
<a
|
||||
href={urlOfArtifact({
|
||||
filepath: file,
|
||||
threadId: threadId,
|
||||
download: true,
|
||||
})}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<Button variant="ghost">
|
||||
<Button variant="ghost" asChild>
|
||||
<a
|
||||
href={urlOfArtifact({
|
||||
filepath: file,
|
||||
threadId: threadId,
|
||||
download: true,
|
||||
})}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<DownloadIcon className="size-4" />
|
||||
{t.common.download}
|
||||
</Button>
|
||||
</a>
|
||||
</a>
|
||||
</Button>
|
||||
</CardAction>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
|
||||
@ -280,16 +280,17 @@ function ToolCall({
|
||||
return (
|
||||
<ChainOfThoughtStep
|
||||
key={id}
|
||||
className="cursor-pointer"
|
||||
label={t.toolCalls.viewWebPage}
|
||||
icon={GlobeIcon}
|
||||
onClick={() => {
|
||||
window.open(url, "_blank");
|
||||
}}
|
||||
>
|
||||
<ChainOfThoughtSearchResult>
|
||||
{url && (
|
||||
<a href={url} target="_blank" rel="noopener noreferrer">
|
||||
<a
|
||||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="cursor-pointer"
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
)}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user