GHSA-xhjh-pmcv-23jw

Suggest an improvement
Source
https://github.com/advisories/GHSA-xhjh-pmcv-23jw
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-xhjh-pmcv-23jw/GHSA-xhjh-pmcv-23jw.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-xhjh-pmcv-23jw
Aliases
  • CVE-2026-42040
Downstream
Related
Published
2026-05-05T00:18:03Z
Modified
2026-05-06T15:29:21.463270742Z
Severity
  • 3.7 (Low) CVSS_V3 - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N CVSS Calculator
Summary
Axios: Null Byte Injection via Reverse-Encoding in AxiosURLSearchParams
Details

Vulnerability Disclosure: Null Byte Injection via Reverse-Encoding in AxiosURLSearchParams

Summary

The encode() function in lib/helpers/AxiosURLSearchParams.js contains a character mapping (charMap) at line 21 that reverses the safe percent-encoding of null bytes. After encodeURIComponent('\x00') correctly produces the safe sequence %00, the charMap entry '%00': '\x00' converts it back to a raw null byte.

This is a clear encoding defect: every other charMap entry encodes in the safe direction (literal → percent-encoded), while this single entry decodes in the opposite (dangerous) direction.

Severity: Low (CVSS 3.7) Affected Versions: All versions containing this charMap entry Vulnerable Component: lib/helpers/AxiosURLSearchParams.js:21

CWE

  • CWE-626: Null Byte Interaction Error (Poison Null Byte)
  • CWE-116: Improper Encoding or Escaping of Output

CVSS 3.1

Score: 3.7 (Low)

Vector: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N

| Metric | Value | Justification | |---|---|---| | Attack Vector | Network | Attacker controls input parameters remotely | | Attack Complexity | High | Standard axios request flow (buildURL) uses its own encode function which does NOT have this bug. Only triggered via direct AxiosURLSearchParams.toString() without an encoder, or via custom paramsSerializer delegation | | Privileges Required | None | No authentication needed | | User Interaction | None | No user interaction required | | Scope | Unchanged | Impact limited to HTTP request URL | | Confidentiality | None | No confidentiality impact | | Integrity | Low | Null byte in URL can cause truncation in C-based backends, but requires a vulnerable downstream parser | | Availability | None | No availability impact |

Vulnerable Code

File: lib/helpers/AxiosURLSearchParams.js, lines 13-26

function encode(str) {
  const charMap = {
    '!': '%21',     // literal → encoded (SAFE direction)
    "'": '%27',     // literal → encoded (SAFE direction)
    '(': '%28',     // literal → encoded (SAFE direction)
    ')': '%29',     // literal → encoded (SAFE direction)
    '~': '%7E',     // literal → encoded (SAFE direction)
    '%20': '+',     // standard transformation (SAFE)
    '%00': '\x00',  // LINE 21: encoded → raw null byte (UNSAFE direction!)
  };
  return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {
    return charMap[match];
  });
}

Why the Standard Flow Is NOT Affected

// buildURL.js:36 — uses its OWN encode function (lines 14-20), not AxiosURLSearchParams's
const _encode = (options && options.encode) || encode;  // buildURL's encode

// buildURL.js:53 — passes buildURL's encode to AxiosURLSearchParams
new AxiosURLSearchParams(params, _options).toString(_encode);  // external encoder used

// AxiosURLSearchParams.js:48 — when encoder is provided, internal encode is NOT used
const _encode = encoder ? function(value) { return encoder.call(this, value, encode); } : encode;
//                                                                              ^^^^^^
//                                           internal encode passed as 2nd arg but only used if
//                                           the external encoder explicitly delegates to it

Proof of Concept

import AxiosURLSearchParams from './lib/helpers/AxiosURLSearchParams.js';
import buildURL from './lib/helpers/buildURL.js';

// Test 1: Direct AxiosURLSearchParams (VULNERABLE path)
const params = new AxiosURLSearchParams({ file: 'test\x00.txt' });
const result = params.toString();  // NO encoder → uses internal encode with charMap
console.log('Direct toString():', JSON.stringify(result));
// Output: "file=test\u0000.txt" (contains raw null byte)
console.log('Hex:', Buffer.from(result).toString('hex'));
// Output: 66696c653d74657374002e747874  (00 = null byte)

// Test 2: Via buildURL (NOT vulnerable — standard axios flow)
const url = buildURL('http://example.com/api', { file: 'test\x00.txt' });
console.log('Via buildURL:', url);
// Output: http://example.com/api?file=test%00.txt  (%00 preserved safely)

Verified PoC Output

Direct toString(): "file=test\u0000.txt"
Contains raw null byte: true
Hex: 66696c653d74657374002e747874

Via buildURL: http://example.com/api?file=test%00.txt
Contains raw null byte: false
Contains safe %00: true

Impact Analysis

Primary impact is limited because the standard axios request flow is not affected. However:

  • Direct API users: Applications using AxiosURLSearchParams directly for custom serialization are affected
  • Custom paramsSerializer: A paramsSerializer.encode that delegates to the internal encoder triggers the bug
  • Code defect signal: The directional inconsistency in charMap is a clear coding error with no legitimate use case

If null bytes reach a downstream C-based parser, impacts include URL truncation, WAF bypass, and log injection.

Recommended Fix

Remove the %00 entry from charMap and update the regex:

function encode(str) {
  const charMap = {
    '!': '%21',
    "'": '%27',
    '(': '%28',
    ')': '%29',
    '~': '%7E',
    '%20': '+',
    // REMOVED: '%00': '\x00'
  };
  return encodeURIComponent(str).replace(/[!'()~]|%20/g, function replacer(match) {
    //                                           ^^^^ removed |%00
    return charMap[match];
  });
}

Resources

Timeline

| Date | Event | |---|---| | 2026-04-15 | Vulnerability discovered during source code audit | | 2026-04-16 | Report revised: documented standard-flow limitation, corrected CVSS | | TBD | Report submitted to vendor via GitHub Security Advisory |

Database specific
{
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-05T00:18:03Z",
    "nvd_published_at": "2026-04-24T18:16:30Z",
    "severity": "LOW",
    "cwe_ids": [
        "CWE-116",
        "CWE-626"
    ]
}
References

Affected packages

npm / axios

Package

Affected ranges

Type
SEMVER
Events
Introduced
1.0.0
Fixed
1.15.1

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-xhjh-pmcv-23jw/GHSA-xhjh-pmcv-23jw.json"

npm / axios

Package

Affected ranges

Type
SEMVER
Events
Introduced
0Unknown introduced version / All previous versions are affected
Fixed
0.31.1

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-xhjh-pmcv-23jw/GHSA-xhjh-pmcv-23jw.json"
last_known_affected_version_range
"<= 0.31.0"