Files
multica/server/internal/sanitize/html.go
Jiayuan Zhang 6c5879215d fix: sanitize markdown rendering in comments and shared renderers (#679)
* fix: sanitize markdown rendering in comments and shared renderers

Add rehype-sanitize to both ReadonlyContent and Markdown components so
that raw HTML parsed by rehype-raw is sanitized against a strict
allowlist before reaching the DOM. On the backend, add a bluemonday
sanitization pass when creating and updating comments to strip
dangerous tags as defense-in-depth.

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

* fix: add mention:// protocol to sanitize allowlist and validate file card URLs

- Add mention:// to rehype-sanitize protocols.href in both ReadonlyContent
  and Markdown so @mention links survive sanitization
- Validate data-href on file cards to only allow http(s) URLs, blocking
  javascript: and data: schemes in both frontend click handler and backend
  bluemonday policy
- Narrow class attribute allowlist to specific elements (code, div, span, pre)

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 03:44:30 +08:00

36 lines
1.3 KiB
Go

package sanitize
import (
"regexp"
"github.com/microcosm-cc/bluemonday"
)
// httpURL matches only http:// and https:// URLs — blocks javascript:, data:, etc.
var httpURL = regexp.MustCompile(`^https?://`)
// policy is a shared bluemonday policy that allows safe Markdown HTML while
// stripping dangerous elements (script, iframe, object, embed, style, on*).
//
// Note: bluemonday operates on raw text, so HTML inside Markdown code blocks
// (e.g. ```<script>```) will also be stripped. This is an acceptable trade-off
// for defense-in-depth — the primary sanitization happens in the frontend via
// rehype-sanitize which understands the Markdown AST.
var policy *bluemonday.Policy
func init() {
policy = bluemonday.UGCPolicy()
policy.AllowElements("div", "span")
// Allow file-card data attributes, but restrict data-href to http(s) only
// to prevent javascript: and other dangerous URL schemes.
policy.AllowAttrs("data-type", "data-filename").OnElements("div")
policy.AllowAttrs("data-href").Matching(httpURL).OnElements("div")
policy.AllowAttrs("class").OnElements("code", "div", "span", "pre")
}
// HTML sanitizes user-provided HTML/Markdown content, stripping dangerous
// tags (script, iframe, object, embed, etc.) and event-handler attributes.
func HTML(input string) string {
return policy.Sanitize(input)
}