Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-43971

CVE-2026-43971: cowlib Link Header Smuggling XSS Vulnerability

CVE-2026-43971 is a cross-site scripting flaw in cowlib that enables Link header directive smuggling through unescaped characters. Attackers can force browsers to connect to malicious origins. This article covers technical details, affected versions, impact, and mitigation strategies.

Updated:

CVE-2026-43971 Overview

CVE-2026-43971 is an improper output encoding vulnerability [CWE-116] in ninenines/cowlib, the low-level HTTP library used by the Cowboy Erlang web server. The flaw resides in cow_link:do_link/1, which serializes application-supplied values directly into a Link: response header without escaping or token-grammar validation. An attacker who can influence the target URI, rel value, or attribute keys can smuggle additional directives such as rel="preconnect", rel="preload", or rel="prerender". This forces victim browsers to open out-of-band connections to attacker-controlled origins. The issue affects cowlib versions from 2.9.0 onward.

Critical Impact

Attackers can inject arbitrary Link: header directives, coercing victim browsers into contacting attacker-controlled origins via preconnect, preload, and prerender hints.

Affected Products

  • ninenines/cowlib from version 2.9.0 onward
  • Erlang/OTP web applications using Cowboy that round-trip parsed Link: headers through cow_link:link/1
  • Downstream HTTP frameworks that depend on cowlib for header serialization

Discovery Timeline

  • 2026-08-18 - CVE-2026-43971 published to NVD
  • 2026-08-20 - Last updated in NVD database

Technical Details for CVE-2026-43971

Vulnerability Analysis

The defect lives in cow_link:do_link/1 in src/cow_link.erl. The function interpolates three attacker-influenceable slots — the target URI, the rel value, and attribute keys — directly into the serialized Link: header value. No escaping, quoting, or token-grammar validation is applied before emission.

Because the serializer does not enforce the RFC 8288 grammar, a single unexpected byte breaks out of its intended slot. A > byte in the target closes the URI angle-bracket delimiter early, permitting appended link entries. A " or \ byte in rel terminates the quoted string and opens a new parameter list. Any byte in an attribute key, including whitespace, =, and ", is emitted verbatim.

Browsers act on parsed Link: directives immediately. Injected rel="preconnect", rel="preload", and rel="prerender" values cause victim clients to open TCP, TLS, and HTTP connections to attacker-chosen hosts. This enables tracking, cache pollution, and outbound request smuggling.

Root Cause

The root cause is missing output encoding [CWE-116]. cow_link:do_link/1 concatenates values into the header without validating that each slot conforms to the URI or quoted-string grammar defined in RFC 8288 and RFC 7230.

Attack Vector

An attacker supplies crafted values into any application field that later serializes through cow_link:link/1. Applications that echo parsed Link: headers, expose user-controlled URLs, or accept rel values from untrusted input are exposed. The attack requires no authentication and executes over the network.

text
// Patch excerpt: include/cow_parse.hrl adds URI character validation
(C =:= $() or (C =:= $)) or (C =:= $*) or (C =:= $+) or
(C =:= $,) or (C =:= $;) or (C =:= $=)).

-define(IS_URI_CHAR(C),
	?IS_URI_UNRESERVED(C) or ?IS_URI_GEN_DELIMS(C) or
	?IS_URI_SUB_DELIMS(C) or (C =:= $%)).

-define(IS_VCHAR(C), C =:= $\t; C > 31, C < 127).

Source: GitHub Cowlib Commit 89da27e

Detection Methods for CVE-2026-43971

Indicators of Compromise

  • Outbound Link: response headers containing > characters in the URI slot or unescaped " and \ bytes inside rel values.
  • Server logs showing unexpected rel="preconnect", rel="preload", or rel="prerender" directives originating from user-controlled fields.
  • DNS or NetFlow telemetry showing client browsers connecting to unfamiliar origins immediately after page load.

Detection Strategies

  • Inspect HTTP responses at the proxy or WAF layer for Link: headers containing multiple angle-bracketed URI entries where only one is expected.
  • Audit application code paths that call cow_link:link/1 and identify any that accept untrusted URI, rel, or attribute inputs.
  • Compare deployed cowlib version against the fixed release referenced in the CNA advisory.

Monitoring Recommendations

  • Enable egress monitoring for browser clients to identify preconnect or prerender traffic to unapproved domains.
  • Log full Link: header contents on outbound responses in staging and production for anomaly review.
  • Alert on any Erlang release still shipping cowlib2.9.0 through the last unpatched version.

How to Mitigate CVE-2026-43971

Immediate Actions Required

  • Upgrade cowlib to the patched release that includes commit 89da27e.
  • Audit all invocations of cow_link:link/1 and remove untrusted input from the target, rel, and attribute key slots.
  • Sanitize or reject any application input containing >, ", \, =, or whitespace before it reaches Link header construction.

Patch Information

The upstream fix in ninenines/cowlib adds a new IS_URI_CHAR macro in include/cow_parse.hrl and rejects invalid characters when building the Link: header in src/cow_link.erl. Applications should rebuild against the patched dependency and redeploy. Refer to the OSV entry EEF-CVE-2026-43971 for ecosystem tracking.

Workarounds

  • Strip or URL-encode >, ", and \ from any user-supplied value before passing it to cow_link:link/1.
  • Restrict rel values to a server-side allowlist such as next, prev, or canonical.
  • Disable pass-through of parsed Link: headers from upstream services until the library is upgraded.
bash
# Example rebar3 dependency pin after upgrading cowlib
{deps, [
  {cowboy, "~> 2.x"},
  {cowlib, {git, "https://github.com/ninenines/cowlib", {ref, "89da27ee4c241f5d649ba7d9b7f2188918af6cea"}}}
]}.

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.