{"id":"CVE-2026-43966","kind":"vulnerability","aliases":["CVE-2026-43966","GHSA-w4f7-4cxr-rv3c"],"related":[],"title":"cowboy and gun affected by an HTTP Request/Response Splitting vulnerability","description":"Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Request/Response Splitting') vulnerability in ninenines cowlib allows HTTP response splitting via non-VCHAR bytes in structured-fields string values.\n\ncow_http_struct_hd:escape_string/2 in cowlib only escapes \\ and \", passing all other bytes through verbatim. This creates an encoder/decoder asymmetry: the matching parser accepts only printable ASCII (0x20–0x7E, excluding \" and \\), but the encoder emits any byte including CR and LF. An application that builds a structured HTTP header via cow_http_struct_hd:item/1 (or a higher-level wrapper such as cow_http_hd:wt_protocol/1) from attacker-controlled input can have \\r\\n injected into the serialized header value. Once on the wire, the injected CRLF terminates the current header and any following bytes are interpreted as a new header, enabling HTTP response splitting.\n\nThis issue affects cowlib: from 2.9.0 before 2.22.0.","summary":"The cowlib library, used by Erlang web servers cowboy and gun, fails to escape carriage return and line feed bytes when encoding structured HTTP header string values. An attacker who controls part of a header value can inject a line break and add arbitrary headers or a second response.","severity":"medium","cvss":6.3,"epss":0.00259,"exploited":false,"exploited_at":null,"products":[{"name":"cowboy","fixed":["2.16.0"],"affected":"< 2.16.0","ecosystem":"hex"},{"name":"gun","fixed":["2.4.0"],"affected":"< 2.4.0","ecosystem":"hex"},{"name":"ninenines cowlib","fixed":["2.16.0"],"affected":">= 2.9.0, < 2.16.0","ecosystem":"vendor"}],"ecosystems":["hex","vendor"],"tags":["cowboy","cowlib","cwe-113","erlang","gun","hex","package"],"not_affected_if":["fixed-header-values","no-user-input-in-headers"],"how_to_check":"- Check whether the project depends on `cowboy` or `gun` (`rebar.lock`, `mix.lock`, or `rebar3 tree`) and read the locked version.\n- Check whether application code calls `cow_http_struct_hd:item/1` or `cow_http_hd:wt_protocol/1` with user-supplied input.","fix":"- `cowboy` moves to `2.16.0`\n- `gun` moves to `2.4.0`","status":"open","published_at":"2026-06-08T17:16:43+00:00","first_seen_at":"2026-11-12T16:42:18+00:00","triaged_at":"2026-11-12T16:43:35+00:00","updated_at":"2026-11-12T17:09:44+00:00","category":"package","confidence":0.7,"triage":{"at":"2026-11-12T16:43:35Z","model":"claude-haiku-5-5","output":{"fix":"- `cowboy` moves to `2.16.0`\n- `gun` moves to `2.4.0`","reach":"internet","title":"cowboy and gun: CRLF injection lets attackers split HTTP responses","impact":"medium","summary":"The cowlib library, used by Erlang web servers cowboy and gun, fails to escape carriage return and line feed bytes when encoding structured HTTP header string values. An attacker who controls part of a header value can inject a line break and add arbitrary headers or a second response.","audience":"developers","category":"package","nicknames":[],"who_cares":["erlang","cowboy","gun","hex","cowlib"],"confidence":0.7,"fix_status":"available","needs_auth":"unknown","worst_case":"Attacker injects headers or a second response into victim traffic","analyst_note":"","how_to_check":"- Check whether the project depends on `cowboy` or `gun` (`rebar.lock`, `mix.lock`, or `rebar3 tree`) and read the locked version.\n- Check whether application code calls `cow_http_struct_hd:item/1` or `cow_http_hd:wt_protocol/1` with user-supplied input.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["fixed-header-values","no-user-input-in-headers"],"who_is_affected":"Exposure requires an application built on cowboy or gun that passes attacker-controlled data into structured header encoding through cow_http_struct_hd:item/1 or cow_http_hd:wt_protocol/1. Applications that only use fixed header values or do not build structured headers from user input are not reachable through this path.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"unknown","severity_if_unknown":"unknown"},"cost_usd":0.000798,"input_tokens":4916,"output_tokens":613,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-113':29B '-2026':12A,20A '-43966':13A,21A '0x20':142C '0x7e':143C '2.22.0':230C '2.9.0':228C '4cxr':17A 'accept':138C 'add':76B 'affect':4A,225C 'allow':98C 'applic':157C 'arbitrari':77B 'ascii':141C 'asymmetri':134C 'attack':62B,185C 'attacker-control':184C 'break':74B 'build':159C 'byte':53B,106C,127C,151C,212C 'carriag':48B 'control':64B,186C 'cow':113C,165C,178C 'cowboy':1A,22A,26B,42B 'cowlib':25A,27B,35B,97C,120C,226C 'cr':153C 'creat':131C 'crlf':86C,204C 'current':207C 'cve':11A,19A 'cwe':28B 'emit':149C 'enabl':219C 'encod':55B,148C 'encoder/decoder':133C 'erlang':30B,39B 'escap':47B,117C,122C 'exclud':144C 'fail':45B 'feed':52B 'field':110C 'follow':211C 'ghsa':15A 'ghsa-w4f7-4cxr-rv3c':14A 'gun':3A,23A,31B,44B 'hd':116C,168C,180C 'header':58B,68B,78B,90C,163C,196C,208C,218C 'hex':32B 'higher':173C 'higher-level':172C 'http':7A,57B,89C,91C,99C,114C,162C,166C,179C,220C 'improp':83C 'includ':152C 'inject':71B,192C,203C 'input':187C 'interpret':214C 'issu':224C 'item/1':169C 'level':174C 'lf':155C 'librari':36B 'line':51B,73B 'match':136C 'n':191C 'neutral':84C 'new':217C 'ninenin':96C 'ninenines':24A 'non':104C 'non-vchar':103C 'packag':33B 'parser':137C 'part':65B 'pass':124C 'printabl':140C 'protocol/1':182C 'r':190C 'request/response':8A,92C 'respons':82B,100C,221C 'return':49B 'rv3c':18A 'second':81B 'sequenc':87C 'serial':195C 'server':41B 'split':9A,93C,101C,222C 'string':59B,111C 'string/2':118C 'struct':115C,167C 'structur':56B,109C,161C 'structured-field':108C 'termin':205C 'use':37B 'valu':60B,69B,112C,197C 'vchar':105C 'verbatim':129C 'via':102C,164C 'vulner':10A,94C 'w4f7':16A 'web':40B 'wire':201C 'wrapper':175C 'wt':181C","nicknames":[],"mitigations":[],"who_affected":"Exposure requires an application built on cowboy or gun that passes attacker-controlled data into structured header encoding through cow_http_struct_hd:item/1 or cow_http_hd:wt_protocol/1. Applications that only use fixed header values or do not build structured headers from user input are not reachable through this path.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["cowboy","cowlib","gun","nineninescowlib"],"ptokens":["cowboy","cowlib","gun","ninenines"],"labels":["cowboy","cowlib","cwe113","erlang","gun","hex","medium","package","vendor"],"campaign_type":null,"search_a":"'-2026':12A,20A '-43966':13A,21A '4cxr':17A 'affect':4A 'cowboy':1A,22A 'cowlib':25A 'cve':11A,19A 'ghsa':15A 'ghsa-w4f7-4cxr-rv3c':14A 'gun':3A,23A 'http':7A 'ninenines':24A 'request/response':8A 'rv3c':18A 'split':9A 'vulner':10A 'w4f7':16A","search_b":"'-113':29B 'add':76B 'arbitrari':77B 'attack':62B 'break':74B 'byte':53B 'carriag':48B 'control':64B 'cowboy':26B,42B 'cowlib':27B,35B 'cwe':28B 'encod':55B 'erlang':30B,39B 'escap':47B 'fail':45B 'feed':52B 'gun':31B,44B 'header':58B,68B,78B 'hex':32B 'http':57B 'inject':71B 'librari':36B 'line':51B,73B 'packag':33B 'part':65B 'respons':82B 'return':49B 'second':81B 'server':41B 'string':59B 'structur':56B 'use':37B 'valu':60B,69B 'web':40B","search_c":"'0x20':142C '0x7e':143C '2.22.0':230C '2.9.0':228C 'accept':138C 'affect':225C 'allow':98C 'applic':157C 'ascii':141C 'asymmetri':134C 'attack':185C 'attacker-control':184C 'build':159C 'byte':106C,127C,151C,212C 'control':186C 'cow':113C,165C,178C 'cowlib':97C,120C,226C 'cr':153C 'creat':131C 'crlf':86C,204C 'current':207C 'emit':149C 'enabl':219C 'encod':148C 'encoder/decoder':133C 'escap':117C,122C 'exclud':144C 'field':110C 'follow':211C 'hd':116C,168C,180C 'header':90C,163C,196C,208C,218C 'higher':173C 'higher-level':172C 'http':89C,91C,99C,114C,162C,166C,179C,220C 'improp':83C 'includ':152C 'inject':192C,203C 'input':187C 'interpret':214C 'issu':224C 'item/1':169C 'level':174C 'lf':155C 'match':136C 'n':191C 'neutral':84C 'new':217C 'ninenin':96C 'non':104C 'non-vchar':103C 'parser':137C 'pass':124C 'printabl':140C 'protocol/1':182C 'r':190C 'request/response':92C 'respons':100C,221C 'sequenc':87C 'serial':195C 'split':93C,101C,222C 'string':111C 'string/2':118C 'struct':115C,167C 'structur':109C,161C 'structured-field':108C 'termin':205C 'valu':112C,197C 'vchar':105C 'verbatim':129C 'via':102C,164C 'vulner':94C 'wire':201C 'wrapper':175C 'wt':181C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-06-08T17:16:43+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","cvss_by":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-w4f7-4cxr-rv3c","url":"https://github.com/advisories/GHSA-w4f7-4cxr-rv3c","severity":"medium","published_at":"2026-06-08T18:31:51+00:00","modified_at":"2026-11-12T16:42:13+00:00","first_seen_at":"2026-11-12T16:42:18+00:00","fetched_at":"2026-11-12T17:17:56+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-43966","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-43966","severity":null,"published_at":"2026-06-08T17:16:43+00:00","modified_at":"2026-11-09T16:17:33+00:00","first_seen_at":"2026-11-12T17:09:44+00:00","fetched_at":"2026-11-12T17:09:44+00:00","note":null}],"documents":[{"id":136532,"url":"https://github.com/ninenines/cowlib/pull/163#issuecomment-4952645232","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":136533,"url":"https://github.com/ninenines/cowlib/pull/166#issuecomment-5067554701","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":136534,"url":"https://github.com/ninenines/cowlib/commit/4401b858f2229abb3ea115c60924f6c77e5f8aa3","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":136535,"url":"https://github.com/ninenines/cowlib/commit/a8b793db3d6ffe91d62f81baf41b1dab4cd78fb6","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":136635,"url":"https://cna.erlef.org/cves/CVE-2026-43966.html","title":"Third-party advisory: cna.erlef.org","kind":"advisory","source":"nvd","publisher":"research","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Third-party advisory: cna.erlef.org"},{"id":136636,"url":"https://github.com/ninenines/cowboy/commit/f77cb9b5e730e300fffb551db1ba5d1c4ed878ef","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":136639,"url":"https://github.com/ninenines/gun/commit/4f35609eb37109b106a863fc9ba83d7ee64e3e42","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":136640,"url":"https://osv.dev/vulnerability/EEF-CVE-2026-43966","title":"Third-party advisory: osv.dev","kind":"advisory","source":"nvd","publisher":"research","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Third-party advisory: osv.dev"}],"disclosures":[],"exploit_sources":[{"type":"epss","score":0.00259,"url":"https://api.first.org/data/v1/epss?cve=CVE-2026-43966"}],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}