Why
Two pieces of untrusted text decide where a file is written and what a browser executes:
- Path validators:
cleanPathinserver/pages/pages.go, and the artifact, pages, and LFS path rules underciandserver. - Markdown rendering and sanitization:
server/web/markdown.gowithgoldmarkandbluemonday, which sits between a comment body and every visitor.
A path that escapes its root writes outside the intended directory; a sanitizer gap is stored XSS in a trusted origin. Both are string handling, which fuzzing finds faster than reading does.
Scope
- Fuzz the path validators:
..segments, absolute paths, backslashes and Windows separators, NULs, empty components, over-long components, encoded traversal, and Unicode that normalizes into a separator. Assert an accepted path stays under the root it was resolved against. - Fuzz Markdown rendering with a corpus of sanitizer-bypass shapes:
javascript:anddata:URLs, event-handler attributes,<script>in raw HTML, nested entities, and the autolink and table extensions the renderer enables. - Assert the output property directly: no
<script>, noon*=attribute, and no URL scheme outside the allowed set. - Seed from the existing tests and document the local fuzz budget.
Acceptance
go test ./...runs each target’s seed corpus.- Each target survives a documented one-minute run without a finding.
- The sanitizer assertions fail if
bluemonday’s policy is loosened, so the target also guards the policy.
Part of #14.