PolicyEngine / PolicyEngine/policyengine-app-v2
Security: stop rendering raw HTML in blog markdown without sanitization
Nobody has claimed this yet.
- Dominant language
- HTML
- Stars
- 1
- Forks
- 3
- Avg merge
- 1d 50m
- Merged PRs (30d)
- 39
Description
Summary
Blog markdown rendering enables raw HTML without sanitization.
Severity
High
Impact
Raw HTML embedded in markdown is rendered into the DOM instead of escaped, enabling stored XSS if markdown content is ever attacker-controlled or imported from an untrusted source.
Affected code
website/src/components/blog/MarkdownFormatter.tsx:11-14,831-838- mirrored copy in
policyengine-app-v2-blog/app/src/components/blog/MarkdownFormatter.tsx:19-22,890-893
Details
ReactMarkdown is configured with rehypeRaw and no sanitizer.
Expected behavior
Either raw HTML should be disabled or the pipeline should include a strict sanitizer.
Suggested remediation
- Remove
rehypeRaw, or - Add
rehype-sanitizewith an explicit allowlist - Add tests demonstrating malicious HTML is escaped or stripped
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the ReactMarkdown configuration in website/src/components/blog/MarkdownFormatter.tsx and compare the mirrored copy at policyengine-app-v2-blog/app/src/components/blog/MarkdownFormatter.tsx. Check how the current rehypeRaw setup handles malicious HTML, then add coverage showing that HTML is escaped or stripped. Done means both copies disable raw HTML or apply a strict sanitizer and the malicious-input tests pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100