Every CVE Search/ Get API key

CVE-2026-27959

Koa has Host Header Injection via `ctx.hostname`

7.5 HighPublic exploitFix available

Koa is middleware for Node.js using ES2017 async functions. Prior to versions 3.1.2 and 2.16.4, Koa's ctx.hostname API performs naive parsing of the HTTP Host header, extracting everything before the first colon without validating the input conforms to RFC 3986 hostname syntax. When a malformed Host header containing a @ symbol is received, ctx.hostname returns evil[.]com - an attacker-controlled value. Applications using ctx.hostname for URL generation, password reset links, email verification URLs, or routing decisions are vulnerable to Host header injection attacks. Versions 3.1.2 and 2.16.4 fix the issue.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
High
Availability
None

Exploit likelihood

0.39%Up 0.3 points since Feb 26, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.5

Koa has Host Header Injection via `ctx.hostname`

Koa is middleware for Node.js using ES2017 async functions. Prior to versions 3.1.2 and 2.16.4, Koa's ctx.hostname API performs naive parsing of the HTTP Host header, extracting everything before the first colon without validating the input conforms to RFC 3986 hostname syntax. When a malformed Host header containing a @ symbol is received, ctx.hostname returns evil[.]com - an attacker-controlled value. Applications using ctx.hostname for URL generation, password reset links, email verification URLs, or routing decisions are vulnerable to Host header injection attacks. Versions 3.1.2 and 2.16.4 fix the issue.

Record
CVE-2026-27959
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
CVSS 3.1
8.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Weakness
CWE-20, CWE-20
Updated
2026-11-02
EUVDEUVD-2026-8816 8.2

Koa is middleware for Node.js using ES2017 async functions. Prior to versions 3.1.2 and 2.16.4, Koa's ctx.hostname API performs naive parsing of the HTTP Host header, extracting everything before the first colon without validating the input conforms to RFC 3986 hostname syntax. When a malformed Host header containing a @ symbol is received, ctx.hostname returns evil[.]com - an attacker-controlled value. Applications using ctx.hostname for URL generation, password reset links, email verification URLs, or routing decisions are vulnerable to Host header injection attacks. Versions 3.1.2 and 2.16.4 fix the issue.

Record
EUVD-2026-8816
CVSS 3.1
8.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-7gcc-r8m5-44qm 7.5

Koa has Host Header Injection via ctx.hostname

Summary

Koa's ctx.hostname API performs naive parsing of the HTTP Host header, extracting everything before the first colon without validating the input conforms to RFC 3986 hostname syntax. When a malformed Host header containing a @ symbol (e.g., evil.com:[email protected]) is received, ctx.hostname returns evil.com - an attacker-controlled value. Applications using ctx.hostname for URL generation, password reset links, email verification URLs, or routing decisions are vulnerable to Host header injection attacks.

Details

The vulnerability exists in Koa's hostname getter in lib/request.js:

// Koa 2.16.1 - lib/request.js
get hostname() {
  const host = this.host;
  if (!host) return '';
  if ('[' === host[0]) return this.URL.hostname || ''; // IPv6 literal
  return host.split(':', 1)[0];
}

The host getter retrieves the raw header value with HTTP/2 and proxy support:

// Koa 2.16.1 - lib/request.js
get host() {
  const proxy = this.app.proxy;
  let host = proxy && this.get('X-Forwarded-Host');
  if (!host) {
    if (this.req.httpVersionMajor >= 2) host = this.get(':authority');
    if (!host) host = this.get('Host');
  }
  if (!host) return '';
  return host.split(',')[0].trim();
}

The Problem

The parsing logic simply splits on the first : and returns the first segment. There is no validation that the resulting string is a valid hostname per RFC 3986 Section 3.2.2.

RFC 3986 Section 3.2.2 defines the host component as:

host = IP-literal / IPv4address / reg-name
reg-name = *( unreserved / pct-encoded / sub-delims )
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

The @ character is explicitly NOT permitted in the host component - it is the delimiter separating userinfo from host in the authority component.

Attack Vector

When an attacker sends:

Host: evil.com:[email protected]:3000

Koa parses this as:

| API | Returns | Notes | |-----|---------|-------| | ctx.get('Host') | "evil.com:[email protected]:3000" | Raw header | | ctx.hostname | "evil.com" | Attacker-controlled | | ctx.host | "evil.com:[email protected]:3000" | Raw header value | | ctx.origin | "http://evil.com:[email protected]:3000" | Protocol + malformed host |

The ctx.hostname API returns evil.com because the parser splits on the first : without understanding that evil.com:[email protected] is a malformed authority component where evil.com:fake would be interpreted as userinfo by a proper URI parser.

Additional Concern: ctx.origin

Koa's ctx.origin property concatenates protocol and host without validation:

// lib/request.js
get origin() {
  return `${this.protocol}://${this.host}`;
}

Applications using ctx.origin for URL generation receive the full malformed Host header value, creating URLs with embedded credentials that browsers may interpret as userinfo.

HTTP/2 Consideration

Koa explicitly checks httpVersionMajor >= 2 to read the :authority pseudo-header:

if (this.req.httpVersionMajor >= 2) host = this.get(':authority');

The same vulnerability applies - malformed :authority values containing userinfo would be accepted and parsed identically.

PoC

Setup

// server.js
const Koa = require('koa'); 
const app = new Koa();

// Simulates password reset URL generation (common vulnerable pattern)
app.use(async ctx => {
  if (ctx.path === '/forgot-password') {
    const resetToken = 'abc123securtoken';
    const resetUrl = `${ctx.protocol}://${ctx.hostname}/reset?token=${resetToken}`;
    
    ctx.body = {
      message: 'Password reset link generated',
      resetUrl: resetUrl,
      debug: {
        rawHost: ctx.get('Host'),
        parsedHostname: ctx.hostname,
        origin: ctx.origin,
        protocol: ctx.protocol
      }
    };
  }
});

app.listen(3000, () =>…
Record
GHSA-7gcc-r8m5-44qm
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-20, CWE-74
Updated
2026-11-02
NVD 7.5

Koa is middleware for Node.js using ES2017 async functions. Prior to versions 3.1.2 and 2.16.4, Koa's ctx.hostname API performs naive parsing of the HTTP Host header, extracting everything before the first colon without validating the input conforms to RFC 3986 hostname syntax. When a malformed Host header containing a @ symbol is received, ctx.hostname returns evil[.]com - an attacker-controlled value. Applications using ctx.hostname for URL generation, password reset links, email verification URLs, or routing decisions are vulnerable to Host header injection attacks. Versions 3.1.2 and 2.16.4 fix the issue.

Record
CVE-2026-27959
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
CVSS 3.1
8.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Weakness
CWE-20
Updated
2026-11-02
OSV 7.5

Koa has Host Header Injection via `ctx.hostname`

Koa is middleware for Node.js using ES2017 async functions. Prior to versions 3.1.2 and 2.16.4, Koa's ctx.hostname API performs naive parsing of the HTTP Host header, extracting everything before the first colon without validating the input conforms to RFC 3986 hostname syntax. When a malformed Host header containing a @ symbol is received, ctx.hostname returns evil[.]com - an attacker-controlled value. Applications using ctx.hostname for URL generation, password reset links, email verification URLs, or routing decisions are vulnerable to Host header injection attacks. Versions 3.1.2 and 2.16.4 fix the issue.

Record
CVE-2026-27959
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-20
Updated
2026-11-02
OSVGHSA-7gcc-r8m5-44qm 7.5

Koa has Host Header Injection via ctx.hostname

Summary

Koa's ctx.hostname API performs naive parsing of the HTTP Host header, extracting everything before the first colon without validating the input conforms to RFC 3986 hostname syntax. When a malformed Host header containing a @ symbol (e.g., evil.com:[email protected]) is received, ctx.hostname returns evil.com - an attacker-controlled value. Applications using ctx.hostname for URL generation, password reset links, email verification URLs, or routing decisions are vulnerable to Host header injection attacks.

Details

The vulnerability exists in Koa's hostname getter in lib/request.js:

// Koa 2.16.1 - lib/request.js
get hostname() {
  const host = this.host;
  if (!host) return '';
  if ('[' === host[0]) return this.URL.hostname || ''; // IPv6 literal
  return host.split(':', 1)[0];
}

The host getter retrieves the raw header value with HTTP/2 and proxy support:

// Koa 2.16.1 - lib/request.js
get host() {
  const proxy = this.app.proxy;
  let host = proxy && this.get('X-Forwarded-Host');
  if (!host) {
    if (this.req.httpVersionMajor >= 2) host = this.get(':authority');
    if (!host) host = this.get('Host');
  }
  if (!host) return '';
  return host.split(',')[0].trim();
}

The Problem

The parsing logic simply splits on the first : and returns the first segment. There is no validation that the resulting string is a valid hostname per RFC 3986 Section 3.2.2.

RFC 3986 Section 3.2.2 defines the host component as:

host = IP-literal / IPv4address / reg-name
reg-name = *( unreserved / pct-encoded / sub-delims )
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

The @ character is explicitly NOT permitted in the host component - it is the delimiter separating userinfo from host in the authority component.

Attack Vector

When an attacker sends:

Host: evil.com:[email protected]:3000

Koa parses this as:

| API | Returns | Notes | |-----|---------|-------| | ctx.get('Host') | "evil.com:[email protected]:3000" | Raw header | | ctx.hostname | "evil.com" | Attacker-controlled | | ctx.host | "evil.com:[email protected]:3000" | Raw header value | | ctx.origin | "http://evil.com:[email protected]:3000" | Protocol + malformed host |

The ctx.hostname API returns evil.com because the parser splits on the first : without understanding that evil.com:[email protected] is a malformed authority component where evil.com:fake would be interpreted as userinfo by a proper URI parser.

Additional Concern: ctx.origin

Koa's ctx.origin property concatenates protocol and host without validation:

// lib/request.js
get origin() {
  return `${this.protocol}://${this.host}`;
}

Applications using ctx.origin for URL generation receive the full malformed Host header value, creating URLs with embedded credentials that browsers may interpret as userinfo.

HTTP/2 Consideration

Koa explicitly checks httpVersionMajor >= 2 to read the :authority pseudo-header:

if (this.req.httpVersionMajor >= 2) host = this.get(':authority');

The same vulnerability applies - malformed :authority values containing userinfo would be accepted and parsed identically.

PoC

Setup

// server.js
const Koa = require('koa'); 
const app = new Koa();

// Simulates password reset URL generation (common vulnerable pattern)
app.use(async ctx => {
  if (ctx.path === '/forgot-password') {
    const resetToken = 'abc123securtoken';
    const resetUrl = `${ctx.protocol}://${ctx.hostname}/reset?token=${resetToken}`;
    
    ctx.body = {
      message: 'Password reset link generated',
      resetUrl: resetUrl,
      debug: {
        rawHost: ctx.get('Host'),
        parsedHostname: ctx.hostname,
        origin: ctx.origin,
        protocol: ctx.protocol
      }
    };
  }
});

app.listen(3000, () =>…
Record
GHSA-7gcc-r8m5-44qm
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-20, CWE-74
Updated
2026-11-02
Show 4 moreShow less
OSVCLSA-2026-1787657292 No score

TuxCare security update for koa (4 CVEs)

TuxCare rebuilt koa to address 4 CVEs. Fixed in 2.15.3-tuxcare.1.

Record
CLSA-2026-1787657292
Updated
2026-11-02
OSVCLSA-2026-1788264598 No score

TuxCare security update for koa (1 CVE)

TuxCare rebuilt koa to address 1 CVE. Fixed in 1.7.1-tuxcare.3.

Record
CLSA-2026-1788264598
Updated
2026-11-02
OSVCLSA-2026-1792779347 No score

TuxCare security update for koa (4 CVEs)

TuxCare rebuilt koa to address 4 CVEs. Fixed in 2.15.4-tuxcare.1.

Record
CLSA-2026-1792779347
Updated
2026-11-02
OSVROOT-APP-NPM-CVE-2026-27959 No score

CVE-2026-27959 in koa - Patched by Root

Root has patched CVE-2026-27959 in the koa package for Root:npm. Multiple fixed versions available.

Record
ROOT-APP-NPM-CVE-2026-27959
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
koa
npm
3.0.0 up to 3.1.2
3.1.2
koa
npm
before 2.16.4
2.16.4
koa
TuxCare:npm
From an advisory covering 4 CVEs
2.15.3-tuxcare.0 up to 2.15.3-tuxcare.1, plus listed versions
2.15.3
2.15.3-tuxcare.1
koa
TuxCare:npm
1.7.1-tuxcare.0 up to 1.7.1-tuxcare.3, plus listed versions
1.7.11.7.1-tuxcare.11.7.1-tuxcare.2
1.7.1-tuxcare.3
koa
TuxCare:npm
From an advisory covering 4 CVEs
2.15.4-tuxcare.0 up to 2.15.4-tuxcare.1, plus listed versions
2.15.4
2.15.4-tuxcare.1
koa
Root:npm
before 2.15.3-aikido.2
2.15.3-aikido.23.0.3-aikido.22.15.4-aikido.22.15.4-aikido.32.15.4-aikido.42.11.0-aikido.2
@rootio/koa
Root:npm
before 2.15.4-root.io.1
2.15.4-root.io.13.0.3-root.io.12.15.3-root.io.23.0.3-root.io.22.15.4-root.io.22.15.4-root.io.32.15.4-root.io.42.11.0-root.io.2

Public exploits

Links only. Every CVE stores no exploit code.

Public exploits
SourceLinkDate
PoC in GitHubmlouazir/CVE-2026-27959-mini-lab2026-03-09

History

History
RecordedChangedSources
affected, facts
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV, PoC in GitHub

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-27959 is a high vulnerability (CVSS 7.5) in Koajs Koa, published February 26, 2026. Public exploit code exists. EPSS puts the chance of exploitation in the next 30 days at 0.39%, the 33rd percentile. Fixed in koa 3.1.2.

References

Show 6 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open