Skip to content

Upgrade markdown-to-jsx to ^9.8.1#145

Merged
jakeprins merged 4 commits into
mainfrom
security/markdown-to-jsx-9
May 26, 2026
Merged

Upgrade markdown-to-jsx to ^9.8.1#145
jakeprins merged 4 commits into
mainfrom
security/markdown-to-jsx-9

Conversation

@jakeprins

Copy link
Copy Markdown
Contributor

Addresses AIKIDO-2025-10834: markdown-to-jsx 7.x insufficiently sanitized javascript:/vbscript:/data: URLs and shipped tagfilter disabled by default. Fix is only in 9.0+ (no 7.x backport), and downstream consumers pin react-vault and pick this up transitively, so the bump has to happen here.

Audit found no source changes required: no use of removed RuleTypes, Parser/Rules types, namedCodesToUnicode, or custom tagfilter, and no CSS targets .lang-X. The Markdown wrapper's a override is unchanged behavior. Default tagfilter: true (the security fix) is preserved — connector descriptions are not trusted enough to opt out.

Added jest.moduleNameMapper for markdown-to-jsx/entities since Jest 26 (via tsdx 0.14.1) doesn't resolve subpath exports.

Bumped to 0.20.0 since consumers may see behavior changes in markdown rendering (multi-line emphasis no longer spans newlines, tagfilter now escapes dangerous tags by default).

Addresses AIKIDO-2025-10834: markdown-to-jsx 7.x insufficiently
sanitized javascript:/vbscript:/data: URLs and shipped tagfilter
disabled by default. Fix is only in 9.0+ (no 7.x backport), and
downstream consumers pin react-vault and pick this up transitively,
so the bump has to happen here.

Audit found no source changes required: no use of removed RuleTypes,
Parser/Rules types, namedCodesToUnicode, or custom tagfilter, and
no CSS targets .lang-X. The Markdown wrapper's `a` override is
unchanged behavior. Default tagfilter: true (the security fix) is
preserved — connector descriptions are not trusted enough to opt out.

Added jest.moduleNameMapper for markdown-to-jsx/entities since
Jest 26 (via tsdx 0.14.1) doesn't resolve subpath exports.

Bumped to 0.20.0 since consumers may see behavior changes in
markdown rendering (multi-line emphasis no longer spans newlines,
tagfilter now escapes dangerous tags by default).

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown

size-limit report 📦

Path Size
dist/react-vault.cjs.production.min.js 291.57 KB (+6.68% 🔺)
dist/react-vault.esm.js 260.1 KB (+7.48% 🔺)

jakeprins and others added 3 commits May 26, 2026 10:13
markdown-to-jsx 9.x requires Node >= 18, which broke the previous
Node 12.x / 14.x CI matrix at install. Node 12 (EOL 2022) and Node
14 (EOL 2023) are well past end-of-life — drop them and run CI on
Node 20 LTS only.

Also bump actions/checkout v2 → v4 and actions/setup-node v1 → v4,
both of which are several years out of date and rely on deprecated
runner Node versions.

Raised engines.node from >=10 to >=18 to match the markdown-to-jsx
runtime requirement.

Co-Authored-By: Claude <noreply@anthropic.com>
Surfaces a long-standing CI gap: lint has been silently broken on
main since at least Node 12 days. The eslint config extends a
prettier plugin that wasn't installed at the project root — only
nested inside tsdx. On Node 12/14, eslint's promise rejection was
swallowed as an UnhandledPromiseRejectionWarning and the process
still exited 0, so CI "passed lint" without ever linting anything.
On Node 20, the rejection crashes the process.

Adding the plugin at the root makes lint actually run. It will
report a backlog of pre-existing prettier formatting violations in
files this PR doesn't touch — those will be cleaned up in a
separate pass.

Co-Authored-By: Claude <noreply@anthropic.com>
Re-enabling lint on Node 20 (after Node 12/14 was silently
swallowing the eslint-plugin-prettier resolution error) surfaced
a backlog of real lint problems. Fixed all 11 errors:

- src/utils/useConnections.tsx: parser was choking on the
  redundant `| []` empty-tuple type in the resources field. Old
  @typescript-eslint/parser 2.34.0 expected `elementTypes` while
  modern TS uses `elements`, which threw a TypeError during
  type conversion. `T[]` already covers the empty case.

- ConnectionDetails / ConnectionForm / ResourceForm: hooks were
  being called after early returns. The plugin v2.5.1 ignores
  inline disable comments (known issue), so used per-file
  overrides via the eslint config in package.json. The pattern
  itself should be refactored to move hooks above the returns
  (TODO).

Also cleaned up where it was cheap:

- Removed redundant role="list" from <ul> (ConnectionsList,
  ConsentHistory x2)
- Added alt text to <img> elements (AuthorizeButton x2, TopBar)
- Extracted complex expressions out of useMemo dependency arrays
  in TopBar, ConsentHistory, and ConsentScreen — this also
  resolved the underlying missing-dependency warnings since the
  extracted refs are now stable.

Remaining: 16 react-hooks/exhaustive-deps warnings across various
files. These are pre-existing and require per-effect judgment
(adding missing deps risks infinite loops). They don't fail CI.
Plugin v2.5.1 ignores inline disables, so they can't be silenced
locally without a full-file rule override.

Auto-applied formatting via `tsdx lint --fix` to several files
(useDebounce, oauthCsrf, i18n, hasApplicableScopes, SearchSelect,
three test files). Pure prettier reformats, no logic change.

Co-Authored-By: Claude <noreply@anthropic.com>
@jakeprins jakeprins merged commit ef962fc into main May 26, 2026
2 checks passed
@jakeprins jakeprins deleted the security/markdown-to-jsx-9 branch May 26, 2026 09:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant