fix(ui): keep local file markdown links inert · openclaw/openclaw@fc2d2d5
BryanTegomoh
·
2026-05-26
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -569,6 +569,20 @@ PY
|
569 | 569 | const html = toSanitizedMarkdownHtml("[click](file:///etc/passwd)"); |
570 | 570 | expect(html).toBe("<p><a>click</a></p>\n"); |
571 | 571 | }); |
| 572 | + |
| 573 | +it("strips href from host-local absolute file paths", () => { |
| 574 | +const html = toSanitizedMarkdownHtml( |
| 575 | +"[report.docx](/Users/test/.openclaw/data/skills/output/report.docx)", |
| 576 | +); |
| 577 | +expect(html).toBe("<p><a>report.docx</a></p>\n"); |
| 578 | +}); |
| 579 | + |
| 580 | +it("keeps app-relative links navigable", () => { |
| 581 | +const html = toSanitizedMarkdownHtml("[usage](/usage)"); |
| 582 | +expect(html).toBe( |
| 583 | +'<p><a href="/usage" rel="noreferrer noopener" target="_blank">usage</a></p>\n', |
| 584 | +); |
| 585 | +}); |
572 | 586 | }); |
573 | 587 | |
574 | 588 | describe("ReDoS protection", () => { |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -84,6 +84,8 @@ const MARKDOWN_PARSE_LIMIT = 40_000;
|
84 | 84 | const MARKDOWN_CACHE_LIMIT = 200; |
85 | 85 | const MARKDOWN_CACHE_MAX_CHARS = 50_000; |
86 | 86 | const INLINE_DATA_IMAGE_RE = /^data:image\/[a-z0-9.+-]+;base64,/i; |
| 87 | +const HOST_LOCAL_FILE_HREF_RE = |
| 88 | +/^(?:~\/|\/(?:Users|home|tmp|private\/tmp|var\/folders|private\/var\/folders)\/|\/[A-Za-z]:\/|[A-Za-z]:[\\/])/; |
87 | 89 | const markdownCache = new Map<string, string>(); |
88 | 90 | const TAIL_LINK_BLUR_CLASS = "chat-link-tail-blur"; |
89 | 91 | |
@@ -135,6 +137,10 @@ function shouldRenderCodeBlockCopy(env: unknown): boolean {
|
135 | 137 | return (env as Partial<MarkdownRenderEnv> | undefined)?.codeBlockChrome !== "none"; |
136 | 138 | } |
137 | 139 | |
| 140 | +function isHostLocalFileHref(href: string): boolean { |
| 141 | +return HOST_LOCAL_FILE_HREF_RE.test(href.trim()); |
| 142 | +} |
| 143 | + |
138 | 144 | function installHooks() { |
139 | 145 | if (hooksInstalled) { |
140 | 146 | return; |
@@ -150,6 +156,11 @@ function installHooks() {
|
150 | 156 | return; |
151 | 157 | } |
152 | 158 | |
| 159 | +if (isHostLocalFileHref(href)) { |
| 160 | +node.removeAttribute("href"); |
| 161 | +return; |
| 162 | +} |
| 163 | + |
153 | 164 | // Block dangerous URL schemes (javascript:, data:, vbscript:, etc.) |
154 | 165 | try { |
155 | 166 | const url = new URL(href, window.location.href); |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。