Skip to content

fix(docs): sanitize the HTML the schema-driven tables inject - #12304

Open
kozlek wants to merge 1 commit into
devs/kozlek/devs/kozlek/batch-status-data-type/read-documented-enum-values-one-shared-reader--e539de06from
devs/kozlek/devs/kozlek/batch-status-data-type/sanitize-html-schema-driven-tables-inject--ce1642f8
Open

fix(docs): sanitize the HTML the schema-driven tables inject#12304
kozlek wants to merge 1 commit into
devs/kozlek/devs/kozlek/batch-status-data-type/read-documented-enum-values-one-shared-reader--e539de06from
devs/kozlek/devs/kozlek/batch-status-data-type/sanitize-html-schema-driven-tables-inject--ce1642f8

Conversation

@kozlek

@kozlek kozlek commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

renderMarkdown output goes straight into dangerouslySetInnerHTML in
six tables, and it did not filter URL protocols: remark-rehype emits an
<a> for any link target whatever its scheme, so a javascript: link in
a synced description would have rendered as a live link.

Raw HTML was never a way in — remark-rehype runs without
allowDangerousHtml, so it is discarded before becoming a node — which
makes URL filtering the whole of what rehype-sanitize adds here. It
sits after rehype-raw so that if a caller ever does enable
allowDangerousHtml, the embedded markup is parsed and then sanitized
rather than passed through opaque.

Every input today is first-party: descriptions generated by our own
engine and delivered by our own sync bot. So this is defence in depth
rather than a live exposure — but "the input is trustworthy" is a
property of the six current callers, not of the function, and the output
lands somewhere that makes the distinction expensive to get wrong later.

The tests separate the two guarantees on purpose. Asserting all four
cases together would have been misleading: three of them pass with the
sanitizer removed, because they test the markdown pipeline discarding raw
HTML rather than anything the sanitizer does. Only the URL-protocol cases
fail if it goes.

Output is unchanged across every description the two schemas publish.

Part of MRGFY-8330

Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com

Depends-On: #12293

@mergify
mergify Bot had a problem deploying to Mergify Merge Protections August 4, 2026 17:10 Failure
@kozlek

kozlek commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

This pull request is part of a Mergify stack:

# Pull Request Link
1 fix(docs): show accepted values for API parameters typed by a shared enum #12299
2 refactor(docs): read documented enum values through one shared reader #12293
3 fix(docs): sanitize the HTML the schema-driven tables inject #12304 👈
4 feat(docs): switch to the namespaced documented-data-type marker #12319
5 feat(docs): document the batch status data type #12263

@mergify

mergify Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🔴 3 of 7 protections blocking · waiting on 👀 reviews and ⛓️ dependency

Protection Waiting on
🔴 ⛓️ Depends-On Requirements ⛓️ dependency
🔴 👀 Review Requirements 👀 reviews
🔴 🔎 Reviews 👀 reviews
🟢 🤖 Continuous Integration
🟢 Enforce conventional commit
🟢 📕 PR description
🟢 🚦 Auto-queue

🔴 ⛓️ Depends-On Requirements

Waiting for

This rule is failing.

Requirement based on the presence of Depends-On in the body of the pull request

🔴 👀 Review Requirements

Waiting for

  • #approved-reviews-by >= 2
This rule is failing.
  • any of:
    • #approved-reviews-by >= 2
    • author = dependabot[bot]
    • all of:
      • author = mergify-ci-bot
      • -head ~= ^docs-agent/

🔴 🔎 Reviews

Waiting for

  • #review-requested = 0
This rule is failing.
  • #review-requested = 0
  • #changes-requested-reviews-by = 0
  • #review-threads-unresolved = 0

Show 4 satisfied protections

🟢 🤖 Continuous Integration

  • all of:
    • check-success = build
    • check-success = lint
    • check-success = test
    • any of:
      • check-success = test-broken-links
      • label = ignore-broken-links
    • any of:
      • check-success=Cloudflare Pages
      • -head-repo-full-name~=^Mergifyio/

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|internal|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?!?:

🟢 📕 PR description

  • body ~= (?ms:.{48,})

🟢 🚦 Auto-queue

When all merge protections are satisfied, this pull request will be queued automatically.

@mergify
mergify Bot requested a review from a team August 4, 2026 17:13
@kozlek
kozlek force-pushed the devs/kozlek/devs/kozlek/batch-status-data-type/read-documented-enum-values-one-shared-reader--e539de06 branch from 3c3d836 to f747840 Compare August 5, 2026 13:05
@kozlek
kozlek force-pushed the devs/kozlek/devs/kozlek/batch-status-data-type/sanitize-html-schema-driven-tables-inject--ce1642f8 branch from 4455148 to 87b0bd3 Compare August 5, 2026 13:05
@kozlek

kozlek commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Revision history

# Type Changes Reason Date
1 initial 4455148 2026-08-05 13:05 UTC
2 rebase 4455148 → 87b0bd3 (rebase only) 2026-08-05 13:05 UTC
3 rebase 87b0bd3 → 08912d8 (rebase only) 2026-08-05 13:52 UTC
4 rebase 08912d8 → 452a467 (rebase only) 2026-08-05 14:00 UTC

@mergify
mergify Bot had a problem deploying to Mergify Merge Protections August 5, 2026 13:05 Failure
@kozlek
kozlek marked this pull request as ready for review August 5, 2026 13:40
@kozlek
kozlek force-pushed the devs/kozlek/devs/kozlek/batch-status-data-type/read-documented-enum-values-one-shared-reader--e539de06 branch from f747840 to 4b1ec1f Compare August 5, 2026 13:52
@kozlek
kozlek force-pushed the devs/kozlek/devs/kozlek/batch-status-data-type/sanitize-html-schema-driven-tables-inject--ce1642f8 branch from 87b0bd3 to 08912d8 Compare August 5, 2026 13:52
@mergify
mergify Bot had a problem deploying to Mergify Merge Protections August 5, 2026 13:54 Failure
`renderMarkdown` output goes straight into `dangerouslySetInnerHTML` in
six tables, and it did not filter URL protocols: `remark-rehype` emits an
`<a>` for any link target whatever its scheme, so a `javascript:` link in
a synced description would have rendered as a live link.

Raw HTML was never a way in — `remark-rehype` runs without
`allowDangerousHtml`, so it is discarded before becoming a node — which
makes URL filtering the whole of what `rehype-sanitize` adds here. It
sits after `rehype-raw` so that if a caller ever does enable
`allowDangerousHtml`, the embedded markup is parsed and then sanitized
rather than passed through opaque.

Every input today is first-party: descriptions generated by our own
engine and delivered by our own sync bot. So this is defence in depth
rather than a live exposure — but "the input is trustworthy" is a
property of the six current callers, not of the function, and the output
lands somewhere that makes the distinction expensive to get wrong later.

The tests separate the two guarantees on purpose. Asserting all four
cases together would have been misleading: three of them pass with the
sanitizer removed, because they test the markdown pipeline discarding raw
HTML rather than anything the sanitizer does. Only the URL-protocol cases
fail if it goes.

Output is unchanged across every description the two schemas publish.

Part of MRGFY-8330

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Change-Id: Ice1642f855d6698b65a034e398affbce16f822a6
@kozlek
kozlek force-pushed the devs/kozlek/devs/kozlek/batch-status-data-type/read-documented-enum-values-one-shared-reader--e539de06 branch from 4b1ec1f to b5e84ba Compare August 5, 2026 14:01
@kozlek
kozlek force-pushed the devs/kozlek/devs/kozlek/batch-status-data-type/sanitize-html-schema-driven-tables-inject--ce1642f8 branch from 08912d8 to 452a467 Compare August 5, 2026 14:01
@mergify
mergify Bot had a problem deploying to Mergify Merge Protections August 5, 2026 14:02 Failure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant