VYPR
Medium severity5.4NVD Advisory· Published Apr 6, 2026· Updated Apr 20, 2026

CVE-2026-35166

CVE-2026-35166

Description

Hugo is a static site generator. From 0.60.0 to before 0.159.2, links and image links in the default markdown to HTML renderer are not properly escaped. Hugo users who trust their Markdown content or have custom render hooks for links and images are not affected. This vulnerability is fixed in 0.159.2.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/gohugoio/hugoGo
>= 0.60.0, < 0.159.20.159.2

Affected products

3
  • Gohugo/Hugo3 versions
    cpe:2.3:a:gohugo:hugo:*:*:*:*:*:linux:*:*+ 2 more
    • cpe:2.3:a:gohugo:hugo:*:*:*:*:*:linux:*:*range: >=0.60.0,<0.159.2
    • cpe:2.3:a:gohugo:hugo:*:*:*:*:*:macos:*:*range: >=0.60.0,<0.159.2
    • cpe:2.3:a:gohugo:hugo:*:*:*:*:*:windows:*:*range: >=0.60.0,<0.159.2

Patches

1
479fe6c65493

Fix potential content XSS by escaping dangerous URLs in links and images

https://github.com/gohugoio/hugoBjørn Erik PedersenApr 1, 2026via ghsa
2 files changed · +41 6
  • markup/goldmark/goldmark_integration_test.go+30 0 modified
    @@ -1035,3 +1035,33 @@ foo[^1] and bar[^2]
     		"<p>foo<sup id=\"hb5cdcabc9e678612fnref:1\"><a href=\"#hb5cdcabc9e678612fn:1\" class=\"footnote-ref\" role=\"doc-noteref\">1</a></sup> and bar<sup id=\"hb5cdcabc9e678612fnref:2\"><a href=\"#hb5cdcabc9e678612fn:2\" class=\"footnote-ref\" role=\"doc-noteref\">2</a></sup></p>\n<div class=\"footnotes\" role=\"doc-endnotes\">\n<hr>\n<ol>\n<li id=\"hb5cdcabc9e678612fn:1\">\n<p>footnote one&#160;<a href=\"#hb5cdcabc9e678612fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\">back</a></p>\n</li>\n<li id=\"hb5cdcabc9e678612fn:2\">\n<p>footnote two&#160;<a href=\"#hb5cdcabc9e678612fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\">back</a></p>\n</li>\n</ol>\n</div>",
     	)
     }
    +
    +func TestRenderLinkDefaultDangerous(t *testing.T) {
    +	t.Parallel()
    +
    +	/*
    +		Content: <p>Link: <a href="javascript:alert(1)">Click me</a>
    +		AutoLink: <a href="">javascript:alert(1)</a>
    +		Image: <img src="javascript:alert(1)" alt="alt"></p>
    +	*/
    +
    +	files := `
    +-- content/p1.md --
    +---
    +title: "p1"
    +---
    +Link: [Click me](&#106;avascript:alert(1))
    +AutoLink: <javascript:alert(2)>
    +Image: ![alt](&#106;avascript:alert(3))
    +-- layouts/all.html --
    +Content: {{ .Content }}
    +`
    +
    +	b := hugolib.Test(t, files)
    +
    +	b.AssertFileContent("public/p1/index.html",
    +		`! alert(1)"`,
    +		`! href="javascript:alert(2)"`,
    +		`! alert(3)"`,
    +	)
    +}
    
  • markup/goldmark/render_hooks.go+11 6 modified
    @@ -230,8 +230,9 @@ func (r *hookedRenderer) renderImageDefault(w util.BufWriter, source []byte, nod
     	}
     	n := node.(*ast.Image)
     	_, _ = w.WriteString("<img src=\"")
    -	if r.Unsafe || !html.IsDangerousURL(n.Destination) {
    -		_, _ = w.Write(util.EscapeHTML(util.URLEscape(n.Destination, true)))
    +	dest := util.URLEscape(n.Destination, true)
    +	if r.Unsafe || !html.IsDangerousURL(dest) {
    +		_, _ = w.Write(util.EscapeHTML(dest))
     	}
     	_, _ = w.WriteString(`" alt="`)
     	r.renderTexts(w, source, n)
    @@ -375,8 +376,9 @@ func (r *hookedRenderer) renderLinkDefault(w util.BufWriter, source []byte, node
     	n := node.(*ast.Link)
     	if entering {
     		_, _ = w.WriteString("<a href=\"")
    -		if r.Unsafe || !html.IsDangerousURL(n.Destination) {
    -			_, _ = w.Write(util.EscapeHTML(util.URLEscape(n.Destination, true)))
    +		dest := util.URLEscape(n.Destination, true)
    +		if r.Unsafe || !html.IsDangerousURL(dest) {
    +			_, _ = w.Write(util.EscapeHTML(util.EscapeHTML(dest)))
     		}
     		_ = w.WriteByte('"')
     		if n.Title != nil {
    @@ -445,12 +447,15 @@ func (r *hookedRenderer) renderAutoLinkDefault(w util.BufWriter, source []byte,
     	}
     
     	_, _ = w.WriteString(`<a href="`)
    -	url := r.autoLinkURL(n, source)
    +	url := util.URLEscape(r.autoLinkURL(n, source), false)
    +
     	label := n.Label(source)
     	if n.AutoLinkType == ast.AutoLinkEmail && !bytes.HasPrefix(bytes.ToLower(url), []byte("mailto:")) {
     		_, _ = w.WriteString("mailto:")
     	}
    -	_, _ = w.Write(util.EscapeHTML(util.URLEscape(url, false)))
    +	if r.Unsafe || !html.IsDangerousURL(url) {
    +		_, _ = w.Write(util.EscapeHTML(url))
    +	}
     	if n.Attributes() != nil {
     		_ = w.WriteByte('"')
     		html.RenderAttributes(w, n, html.LinkAttributeFilter)
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.