diff --git a/packages/coding-agent/src/core/export-html/template.js b/packages/coding-agent/src/core/export-html/template.js index 3f4c40f6..27dff747 100644 --- a/packages/coding-agent/src/core/export-html/template.js +++ b/packages/coding-agent/src/core/export-html/template.js @@ -881,7 +881,7 @@ const images = getResultImages(); if (images.length === 0) return ''; return '
' + - images.map(img => ``).join('') + + images.map(img => ``).join('') + '
'; }; @@ -1148,7 +1148,7 @@ if (images.length > 0) { html += '
'; for (const img of images) { - html += ``; + html += ``; } html += '
'; } diff --git a/packages/coding-agent/test/export-html-xss.test.ts b/packages/coding-agent/test/export-html-xss.test.ts index 077a0d12..88f4298e 100644 --- a/packages/coding-agent/test/export-html-xss.test.ts +++ b/packages/coding-agent/test/export-html-xss.test.ts @@ -25,4 +25,10 @@ describe("export HTML markdown link sanitization", () => { expect(templateJs).not.toMatch(/\$\{img\.mimeType\}/); expect(templateJs).toMatch(/escapeHtml\(img\.mimeType/); }); + + it("escapes image data attributes", () => { + // Image data is embedded in src attributes and must not allow attribute breakout. + expect(templateJs).not.toMatch(/;base64,\$\{img\.data\}"/); + expect(templateJs).toMatch(/;base64,\$\{escapeHtml\(img\.data \|\| (?:''|"")\)\}"/); + }); });