Skip to content

fix(threat-composer): Show base64 diagrams in the threat model view - #383

Merged
jessieweiyi merged 1 commit into
mainfrom
fix/markdown-data-image-src
Nov 11, 2026
Merged

jessieweiyi merged 1 commit into
mainfrom
fix/markdown-data-image-src

Conversation

@dboyd13

@dboyd13 dboyd13 commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

Issue # (if applicable)

Closes #382.

Reason for this change

The Threat model view shows a blank space where the architecture and dataflow diagrams should be, whenever the diagram is stored as a base64 image. That covers uploaded images, the bundled example workspaces, and diagrams from threat-composer-ai. Images linked by https URL still show.

The view renders the report as markdown with react-markdown. #346 moved react-markdown from 8.0.7 to 10.1.0. Version 10 passes every URL through defaultUrlTransform, which allows only http, https, irc, ircs, mailto and xmpp. It turns a data: image source into an empty string. Version 8 left image sources alone unless a transformImageUri was passed, and the app passed none.

The Architecture and Dataflow pages set <img src> directly, so they were not affected.

Description of changes

MarkdownViewer passes a urlTransform to react-markdown. It keeps a URL only when it is the src of an img and starts with data:image/<type>;base64,. Every other URL, including links and non-image data: URLs, still goes through defaultUrlTransform.

Alternatives considered and rejected:

  • Pass urlTransform={null} to turn the filter off. That would also let javascript: links through.
  • Render the diagrams outside the markdown. That changes the report layout and the Markdown export path, for no benefit over a narrow allow rule.

Describe any new or updated permissions being added

None.

Description of how you validated changes

  • MarkdownViewer/index.test.tsx (new): base64 PNG and SVG images are kept in markdown and in a raw HTML <img>, https images are kept, a data:text/html image is dropped, and javascript: and data: links are dropped. The three image tests fail without the fix.
  • e2e/tests/preview-and-content.spec.ts: opens the bundled Threat Composer example and checks that both diagrams in the Threat model view have a data:image/png source and decode. It fails without the fix (src is empty).
  • pnpm lint and pnpm build exit 0.
  • pnpm nx run @aws/threat-composer-e2e:e2e (127 passed) and e2e:preview (6 passed) exit 0. e2e:variants and e2e:extension were not run locally.

Checklist

  • The title follows type(scope): Subject. It becomes the commit message on main.
  • The build passes locally. See "Verify a change" in AGENTS.md.
  • If behaviour changed, the docs are updated in this pull request, or the description says why not. This restores earlier behaviour, so no docs change.
  • If this touches an area the threat model covers, the threat model is updated, or the description says why not. The change keeps the default URL filter for links and allows only base64 image sources, which cannot run script when loaded as an <img>.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

react-markdown 10 passes every URL through defaultUrlTransform, which
empties data: image sources, so the Threat model view dropped every
diagram stored as a base64 image. MarkdownViewer now keeps a data:image
base64 URL when it is an img src. Other URLs keep the default filter.
@jessieweiyi
jessieweiyi merged commit cea6632 into main Nov 11, 2026
7 checks passed
@jessieweiyi
jessieweiyi deleted the fix/markdown-data-image-src branch November 11, 2026 22:48
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.0.93 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Threat model view doesn't show base64 diagrams

2 participants