Skip to main content

gomarkdown markdown CVE-2026-102941

| EUVDEUVD-2026-102934 HIGH
Out-of-bounds Read (CWE-125)
2026-10-16 GitHub_M GHSA-cv23-7vc5-jfh7
7.5
CVSS 3.1 · Vendor: GitHub_M
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Send untrusted Markdown with empty link destination
  2. Exploit
    Safelink flag routes destination to IsSafeURL
  3. Execution
    Pre-guard slice url[:nPath] on short URL
  4. Impact
    Uncaught slice-bounds panic crashes process (DoS)

Vulnerability Assessment

Weakness
CWE
ASVS 5.0
V15 - Secure Coding and Architecture Bounds checking, read limits
MITRE ATT&CK

1 technique across 1 tactic: Collection

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

Reachability requires one of two concrete conditions: (1) the application calls markdown.ToHTML to render untrusted Markdown with the html.Safelink flag enabled (html.CommonFlags|html.Safelink), and the input contains an empty or 0/1/2-byte link destination such as [x](), [x](.), or [x](..); or (2) a downstream caller passes a short (0/1/2-byte) attacker-controlled URL directly to the exported parser.IsSafeURL function (no flag required). The primary LIMITING factor is that the default render path with Safelink disabled does NOT reach the vulnerable code, so unpatched deployments that never enable Safelink and never call IsSafeURL directly are not exploitable; no authentication or user interaction is needed once a reachable path exists. Affected versions are < 0.0.0-20260724235538-61af6e1e6971.

Impact

This is a genuine but conditional availability-only issue. The CVSS 3.1 vector (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H = 7.5 HIGH) reflects a remote, unauthenticated, low-complexity trigger with high availability impact and no confidentiality or integrity impact - consistent with the described uncaught slice-bounds panic (CWE-125, out-of-bounds read) in parser.IsSafeURL. No EPSS score, SSVC decision, or CISA KEV entry was supplied in the input, so there is no quantitative exploitation-probability signal and no evidence of active exploitation. The GHSA advisory does contain a fully verified, reproducible crash (exact inputs [x](), ., .., tested with negative controls), so publicly available exploit code effectively exists even though no separate POC flag was provided. The critical nuance that lowers real-world risk below the raw 7.5 is the reachability condition: the end-to-end path through markdown.ToHTML is only reachable when the html.Safelink hardening flag is enabled (not the default render path), or when a downstream directly calls the exported parser.IsSafeURL with a short attacker-controlled URL. The advisory explicitly notes the default no-Safelink path does not reach the bug. Net: a real, easy-to-trigger DoS for the subset of deployments that enable Safelink or call IsSafeURL directly, but not a mass-exploitable, data-exposing flaw - prioritize for affected Go services, deprioritize where Safelink is off.

Exploit ScenarioDerived

An attacker submits untrusted Markdown containing an empty or very short link destination (e.g. [x]()) to a Go service that renders it with markdown.ToHTML and the html.Safelink flag enabled; IsSafeURL slices url[:nPath] before the length guard, triggering a slice-bounds panic that is never recovered and crashes the goroutine/process. A working reproduction with negative controls is published in the GHSA-cv23-7vc5-jfh7 advisory. The AV:N/AC:L vector means the trigger is a single remote, low-complexity request requiring no privileges or user interaction.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Oct 16, 2026

Rendering untrusted Markdown with the Go library github.com/gomarkdown/markdown while the html.Safelink hardening flag is enabled can crash the calling process: parser.IsSafeURL slices a link destination before validating its length and panics on empty, '.', or '..' destinations such as the input [x](), and every version before 0.0.0-20260724235538-61af6e1e6971 is affected. The same panic is reachable without that flag by any downstream caller that passes a 0/1/2-byte attacker-controlled URL directly to the exported parser.IsSafeURL function, yielding a remote, unauthenticated, availability-only denial of service (CVSS 3.1 score 7.5; AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H). Exploitation is conditional rather than universal - the default render path with Safelink disabled never reaches the vulnerable code, there is no confirmed active exploitation (not in CISA KEV), and the upstream advisory itself publicly documents the minimal crash trigger.

RemediationAI

Patch status: upstream fix available (commit/PR); released patched version not independently confirmed as a semver tag. Apply the primary fix by updating the module to the commit-pinned pseudo-version 0.0.0-20260724235538-61af6e1e6971 (commit 61af6e1e69710c5ca13cfbaaaa1bc11bc763a8a9), which relocates the length check ahead of the url[:nPath] slice in parser.IsSafeURL and adds regression tests; run go get github.com/gomarkdown/markdown@61af6e1e6971, re-vendor dependencies, and run govulncheck to confirm the vulnerable symbol is no longer reachable. If an immediate upgrade is not possible, stop enabling the html.Safelink flag (avoid passing html.CommonFlags|html.Safelink or equivalent to the renderer), which removes end-to-end reachability for the ToHTML path - the trade-off is that the built-in URL allow-listing hardening no longer runs, so link destinations must be sanitized upstream of rendering instead, and note that this workaround does nothing for callers that invoke parser.IsSafeURL directly. For code that calls the exported parser.IsSafeURL, add a caller-side guard that rejects inputs shorter than the longest path prefix (length < 3) before invoking it, or wrap the call in recover(); the trade-off is that a recover() masks the panic rather than fixing it and can hide unrelated renderer faults, while the length guard must be applied at every call site. If neither is feasible, prevent untrusted Markdown from reaching Safelink-enabled rendering (for example, restrict the rendering endpoint to trusted content or pre-validate and normalize link destinations) until the dependency can be updated. Advisory reference: https://github.com/gomarkdown/markdown/security/advisories/GHSA-cv23-7vc5-jfh7.

Affected VersionsENISA

markdown < 0.0.0-20260724235538-61af6e1e6971

Affected Packages

go github.com/gomarkdown/markdown fix: 0.0.0-20260724235538-61af6e1e6971
euvd markdown fix: 0.0.0-20260724235538-61af6e1e6971

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 2 packages in go, euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The affected component is a pure-Go Markdown parser/renderer, distributed as the Go module go/github.com/gomarkdown/markdown and tracked generically by the CPE cpe:2.3:a:gomarkdown:markdown:*:*:*:*:*:*:*:*. The root cause class is assigned as CWE-125 (out-of-bounds read), which is accurate at the source level: in parser/parser.go, IsSafeURL iterates the validPaths list ("/", "./", "../", with prefix lengths 1, 2 and 3) and evaluates url[:nPath] before the guard nLink >= nPath that was meant to protect it. In Go, the two-index slice expression url[:nPath] requires nPath <= cap(url) and raises a runtime panic otherwise, so an empty destination (len 0, cap 0), "." (len 1, cap 1) and ".." (len 2, cap 2) all panic on the first prefix longer than the buffer, while "/" is the one explicit non-panic counterexample because it matches the first valid path and returns before a longer prefix is sliced. The adjacent URIs loop in the same function is already guarded correctly, which is the structural signal that this loop deviated; the flaw dates back roughly to 2022 and was confirmed present at upstream HEAD e08cff8. Because Go is memory-safe, the out-of-bounds slice surfaces as an unrecoverable panic in the calling goroutine rather than a disclosed memory read, so the practical impact is availability (C:N/I:N/A:H) and not the information disclosure implied by the source-data tag; there is no recover() in the affected path. The upstream fix commit 61af6e1e69710c5ca13cfbaaaa1bc11bc763a8a9 moves the length check ahead of the slice (or equivalently uses bytes.HasPrefix), a one-line change mirroring the already-correct URIs loop, and adds regression tests for empty, ".", "..", "/" and end-to-end ToHTML rendering with html.CommonFlags|html.Safelink.

Know when Markdown gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (GitHub_M) PRIMARY 7.5 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
vuln.today AI 7.5 HIGH

Remote unauthenticated crafted Markdown reaches the panic with no interaction (AV:N/AC:L/PR:N/UI:N); impact is an unrecoverable process crash only, so A:H with C:N/I:N.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N

Primary rating from Vendor (GitHub_M).

CVSS VectorVendor: GitHub_M

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

Lifecycle Timeline

2
Patch available
Oct 16, 2026 - 17:17 EUVD
CVE Published
Oct 16, 2026 - 15:38 cve.org
HIGH 7.5

DescriptionCVE.org

The package github.com/gomarkdown/markdown is a Go library for parsing Markdown text and rendering as HTML. Prior to 0.0.0-20260724235538-61af6e1e6971, parser.IsSafeURL in parser/parser.go slices url[:nPath] before the len(url) >= nPath guard. A short destination causes a slice-bounds panic when the loop reaches a relative-path prefix for which len(url) < nPath and cap(url) < nPath. The one-byte destination / is an explicit non-panic counterexample because it matches the first valid path and returns before a longer prefix is sliced. Demonstrated panic cases include empty, ., and .. destinations under those conditions. The panic is reachable when markdown.ToHTML renders untrusted Markdown with html.Safelink enabled, including an empty link destination, and is also reachable by callers that pass a short attacker-controlled URL directly to the exported parser.IsSafeURL function. An uncaught panic can terminate the calling process and cause denial of service. This issue is fixed in 0.0.0-20260724235538-61af6e1e6971.

Technical POC Analysis

CWE-125 (out-of-bounds read) manifesting as a Go slice-bounds panic in parser.IsSafeURL, defined in parser/parser.go of the github.com/gomarkdown/markdown module.

Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.

Executive ViewAI

Why It Matters

A denial-of-service flaw in the widely used Go library github.com/gomarkdown/markdown can crash any application that renders untrusted Markdown while the html.Safelink hardening option is enabled, letting an unauthenticated remote party repeatedly take affected services offline; publicly available exploit code exists. The trigger is trivial and publicly documented, and no vendor-released patched version is available, so every build before 0.0.0-20260724235538-61af6e1e6971 is exposed wherever Safelink is enabled or an untrusted short URL is passed straight into parser.IsSafeURL. The impact is availability-only with no data exposure or code execution, but customer-facing comment, content, documentation, and CMS paths that crash and restart can breach SLAs and erode user trust.

Business Impact: Medium
Compensating Controls

No vendor-released patch identified at time of analysis. Interim mitigations: pin to the first unaffected revision 0.0.0-20260724235538-61af6e1e6971 via go.mod replace/go get; disable the html.Safelink flag where rendering untrusted Markdown (noting this removes javascript:-scheme link filtering, so pair it with output sanitization); wrap Markdown rendering and any direct parser.IsSafeURL invocation in a same-goroutine recover() so a panic is contained to a single request; reject or sanitize Markdown link destinations shorter than three bytes, including empty, '.' and '..' targets, before they reach the library; and add edge/WAF filtering and rate limiting for these patterns on internet-facing endpoints.

Threat Intelligence Overview

Prevalence
Medium
moderately popular Go Markdown parsing library, not core infrastructure
Threat Intel
1
1 source
Data Quality
4 sources
Confidence: Medium

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC No
EPSS N/A
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation· derived
None
System Exposure· derived
Open
Automatable· derived
Yes
Human Impact
Medium

Priority Score

38
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +38
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

A buffer overflow occurs when a program writes more data to a memory buffer than it was allocated to hold, causing the excess data to spill into adjacent memory regions.

Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy