From aa3b5ea28792a80a81b7a296c10c4e97281fe77d Mon Sep 17 00:00:00 2001 From: Anthony Ronning <101225832+AnthonyRonning@users.noreply.github.com> Date: Thu, 16 Jul 2026 18:38:48 +0000 Subject: [PATCH 1/2] Prevent Markdown image loading --- frontend/src/components/markdown.test.ts | 39 ++++++++++++++++++++++++ frontend/src/components/markdown.tsx | 3 ++ 2 files changed, 42 insertions(+) create mode 100644 frontend/src/components/markdown.test.ts diff --git a/frontend/src/components/markdown.test.ts b/frontend/src/components/markdown.test.ts new file mode 100644 index 00000000..8fecd44d --- /dev/null +++ b/frontend/src/components/markdown.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it } from "bun:test"; +import React from "react"; +import { renderToStaticMarkup } from "react-dom/server"; + +import { MarkdownContent } from "./markdown"; + +function renderMarkdown(content: string): string { + return renderToStaticMarkup(React.createElement(MarkdownContent, { content })); +} + +describe("MarkdownContent images", () => { + it("renders image alt text without loading remote or local URL schemes", () => { + const rendered = renderMarkdown( + [ + "![remote](https://example.com/tracker.png)", + "![relative](/local-image.png)", + "![data](data:image/png;base64,abc)", + "![blob](blob:https://trymaple.ai/image-id)" + ].join("\n\n") + ); + + expect(rendered).not.toContain(" { + const rendered = renderMarkdown("[Maple](https://trymaple.ai)"); + + expect(rendered).toContain('href="https://trymaple.ai"'); + expect(rendered).toContain(">Maple"); + }); +}); diff --git a/frontend/src/components/markdown.tsx b/frontend/src/components/markdown.tsx index 3f965f99..707e09a3 100644 --- a/frontend/src/components/markdown.tsx +++ b/frontend/src/components/markdown.tsx @@ -435,6 +435,9 @@ function MarkDownContentToMemo(props: { content: string }) { ] ]} components={{ + // Uploaded images use structured input_image parts outside Markdown. Preserve + // useful alt text here without creating an image element or loading its URL. + img: ({ alt }) => (alt ? {alt} : null), pre: (props: JSX.IntrinsicElements["pre"]) => , code: (props: JSX.IntrinsicElements["code"]) => , table: (props: JSX.IntrinsicElements["table"]) => , From afd3bbf71e67addf0253b0725b32e0e10eb9ecff Mon Sep 17 00:00:00 2001 From: Anthony Ronning <101225832+AnthonyRonning@users.noreply.github.com> Date: Thu, 16 Jul 2026 18:50:15 +0000 Subject: [PATCH 2/2] Cover empty-alt Markdown images --- frontend/src/components/markdown.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontend/src/components/markdown.test.ts b/frontend/src/components/markdown.test.ts index 8fecd44d..a2bf2c0d 100644 --- a/frontend/src/components/markdown.test.ts +++ b/frontend/src/components/markdown.test.ts @@ -36,4 +36,12 @@ describe("MarkdownContent images", () => { expect(rendered).toContain('href="https://trymaple.ai"'); expect(rendered).toContain(">Maple"); }); + + it("omits images without alt text", () => { + const rendered = renderMarkdown("![](https://example.com/hidden.png)"); + + expect(rendered).not.toContain("