Repository navigation
Add <img> to safe-outputs HTML tag allowlist #29009
Description
Feature: Allow <img> tags in safe-output content
Context
In #17298 (fixed by #17346, shipped in v0.47.6), the convertXmlTags() allowlist was expanded to include GFM inline tags (abbr, del, ins, kbd, mark, s, span). The same logic should be extended to <img>.
Problem
<img> tags in safe-output bodies (e.g. create-issue, update-issue) are converted to parentheses:
<img align="right" width="120" src="https://example.com/image.png" alt="Mascot" />
becomes:
(img align="right" width="120" src="https://example.com/image.png" alt="Mascot" /)
The only workaround is standard markdown , which doesn't support alignment or sizing.
Why <img> is safe
stripDangerousAttributes() already strips on* event handlers and style from every allowed tag. Adding <img> to allowedTags would produce:
| Input | Output | Safe? |
|---|---|---|
<img src="url" alt="text" width="120" align="right"> |
Preserved as-is | Yes — no dangerous attributes |
<img src=x onerror="alert(1)"> |
<img src=x> |
Yes — onerror stripped by existing logic |
<img src=x onload="steal()"> |
<img src=x> |
Yes — onload stripped |
<img style="position:fixed" src="url"> |
<img src="url"> |
Yes — style stripped |
The src URL is separately validated by sanitizeUrlDomains(), which already redacts URLs from domains not in allowed-domains. So even src is covered.
The existing XSS test (<img src=x onerror="alert(1)">) would continue to pass — the tag is preserved but the dangerous attribute is gone.
Use case: image alignment in dashboard issues
Agentic workflows that maintain living dashboard issues (status reports, watchtowers, audit summaries) benefit from layout control. The most common pattern is floating a small image to the right of a heading or blockquote:
<img align="right" width="120" src="https://example.com/mascot.png" alt="Dashboard mascot" />
> *Status summary text flows to the left of the image...*This is a well-established GitHub Markdown pattern — used across READMEs, issue templates, and profile pages. It works when a human edits the issue manually but breaks when an agent writes the same content through safe-outputs.
 can't replicate this — markdown images don't support align, width, or height.
Suggested change
Add "img" to the allowedTags array in convertXmlTags() (sanitize_content_core.cjs, ~line 630):
const allowedTags = [
"abbr",
"b",
"blockquote",
"br",
"code",
"del",
"details",
"em",
"h1", "h2", "h3", "h4", "h5", "h6",
"hr",
"i",
"img", // <-- add
"ins",
"kbd",
// ...
];Update the existing XSS test to verify onerror/onload are stripped while src, alt, width, height, and align are preserved.
Broader consideration
The same argument applies to other GitHub-supported media/layout tags: <picture>, <source>, <video>, <audio>. But <img> is by far the most common and impactful — happy to keep this scoped to just that.
Environment
- gh-aw version: 0.68.3
- Related: HTML in
update-issuebody gets escaped/mangled #17298, Allow GFM inline HTML tags in update-issue body sanitization #17346
Activity
pelikhan commentedon Apr 30, 2026
@lpcox