BTC
ETH
SOL
BNB
GOLD
XRP
DOGE
ADA
Back to home
Security

[MEDIUM] Security Advisory: Hugo: Certain markdown links are not properly escaped (github.com/gohugoio/hugo)

Hugo, the popular Go-based static site generator, ships with a vulnerability in its default Markdown-to-HTML renderer.

Hugo, the popular Go-based static site generator, ships with a vulnerability in its default Markdown-to-HTML renderer. Links and image links fail to escape properly, opening the door to cross-site scripting (XSS) attacks. The developers patched it in version 0.159.2, released recently. If you render untrusted Markdown content using Hugo’s stock renderer, update immediately—your sites could execute arbitrary JavaScript from malicious links.

Hugo powers over 1 million websites, from personal blogs to corporate docs on platforms like Netlify and GitHub Pages. With 72,000+ GitHub stars and millions of downloads, its footprint is massive. This flaw affects the goldmark renderer, Hugo’s default since version 0.78.0 in 2021. Attackers craft Markdown like [Click me](javascript:alert('XSS')) or data URIs in images, which the renderer converts to raw HTML without sanitizing attributes like href or src. Browsers then execute the payload when users interact.

Who Gets Hit—and Who Doesn’t

Not every Hugo user faces risk. The advisory specifies that sites trusting all Markdown content dodge the bullet, as do those with custom render hooks for links and images. Most Hugo deployments fit this profile: authors control their own posts, typing safe Markdown in editors like VS Code or Forestry. No untrusted input means no exploit path.

Risk spikes for wikis, forums, or CMS hybrids built on Hugo that accept user submissions. Think community docs, comment systems via Webmentions, or headless setups pulling Markdown from GitHub issues. Without safeguards, a single malicious link spreads via search engines or shares. Real-world precedent: Similar Markdown XSS flaws hit Discourse and GitLab in 2022, compromising thousands of instances before patches.

Hugo’s version history adds context. Pre-0.159.2 installs, back to at least 0.78.0 when goldmark became default, carry the issue. Check your go.mod or hugo version output. Netlify and Vercel users auto-deploy latest versions, but self-hosted or Docker-pinned setups lag. Run

hugo version

now. If below 0.159.2, you’re exposed.

Fix It: Patches and Workarounds

Upgrade to v0.159.2 or later. The changelog confirms the fix: goldmark now escapes link destinations and image sources properly, stripping javascript:, vbscript:, and other dangerous schemes. Download from GitHub releases or update via Homebrew, Chocolatey, or Go modules.

No update path? Implement custom render hooks. In your theme’s layouts/_default/_markup/render-link.html, wrap goldmark’s output in a sanitizer:

{{ $url := .Destination | plainify | relURL }}
<a href="{{ $url }}"{{ with .Title }} title="{{ .Title }}"{{ end }}>{{ .Text | .Page.RenderString }}

Do the same for render-image.html. This forces safe URLs. Hugo docs detail hooks here. Test thoroughly—bad hooks break rendering.

For extra layers, pipe output through bluemonday or DOMPurify post-render. Hugo modules like hugo-sanitizer exist, but vet them; third-party code introduces its own risks.

Why This Matters for Security and Ops

XSS via Markdown isn’t novel—it’s a persistent trap in static generators. Hugo’s speed and simplicity lure devs away from heavy CMSes like WordPress, but defaults assume trusted input. This advisory reminds us: static doesn’t mean secure. Attackers scan for outdated Hugo via Shodan (thousands of exposed /hugo-version endpoints), then probe for user content.

Implications ripple to supply chains. Themes from Hugo Themes gallery often lack hooks, amplifying exposure. Enterprise users with compliance needs (SOC2, GDPR) must audit now. Post-patch, monitor logs for javascript: attempts—signs of prior probes.

Bottom line: Hugo fixed this fast, as expected from a mature project. But don’t sleep on it. Scan your sites, update, add hooks if needed. In security, “trust your content” is a weak defense; assume breach and harden accordingly. Hugo remains a top choice—fast builds, no database—but vigilance keeps it that way.

April 4, 2026 · 3 min · 13 views · Source: GitHub Security

Related