Lack of data validation - Type confusion In node-axios
Description
Axios: Null Byte Injection via Reverse-Encoding in AxiosURLSearchParams
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)...
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;...
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)...
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': '+',...
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 |
Mitigation
Update Impact
Minimal update. May introduce new vulnerabilities or breaking changes.
Ecosystem | Package | Affected version | Patched versions |
|---|---|---|---|
debian 11 | - | ||
debian 12 | - | ||
debian 13 | - | ||
debian 14 | 1.15.2-1 | ||
npm | 1.15.1, 0.31.1 |
Aliases
References