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

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

Mitigation

Update Impact

Minimal update. May introduce new vulnerabilities or breaking changes.

Ecosystem
Package
Affected version
Patched versions