ComposioHQ/composio · critical · UnsafePathComponentError

Refusing to write {label} containing a NUL byte: {name!r}

Error message

Refusing to write {label} containing a NUL byte: {name!r}

What it means

safe_basename rejects filenames containing a NUL byte (\x00). NUL cannot appear in a filesystem path on Linux or Windows and would truncate/error at open() time; it is also a classic path-injection marker.

Source

Thrown at python/composio/utils/safe_path.py:177

    both basename to ``""``, which makes an output path equal to its own
    directory and surfaces as ``IsADirectoryError`` at write time.

    :raises UnsafePathComponentError: when ``name`` yields no usable basename or
        is unsafe to write.
    """
    if not isinstance(name, str):
        raise UnsafePathComponentError(
            f"Refusing to write a non-string {label}: {name!r}"
        )

    raw_basename = PureWindowsPath(name).name
    if not raw_basename or not raw_basename.strip() or set(raw_basename) == {"."}:
        raise UnsafePathComponentError(
            f"Path traversal detected: {label} {name!r} leaves no usable "
            "basename to write to."
        )
    if "\x00" in raw_basename:
        raise UnsafePathComponentError(
            f"Refusing to write {label} containing a NUL byte: {name!r}"
        )
    if any(ord(char) < 32 or char in '<>:"|?*' for char in raw_basename):
        raise UnsafePathComponentError(
            f"Refusing to write {label} containing characters reserved by "
            f"Windows: {name!r}"
        )
    if raw_basename.endswith((" ", ".")):
        raise UnsafePathComponentError(
            f"Refusing to write {label} ending in a space or dot: {name!r}"
        )

    basename = raw_basename.strip()
    try:
        encoded_length = len(os.fsencode(basename))
    except UnicodeEncodeError as e:
        raise UnsafePathComponentError(
            f"Refusing to write {label} containing invalid Unicode: {name!r}"

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Strip or reject NUL-containing strings before filename handling
  2. Treat a NUL byte in any path-ish field as malicious input and drop the whole request

Example fix

# before
secure_basename_join(base, name)
# after
if "\x00" in name:
    raise ValueError("invalid filename")
secure_basename_join(base, name)
Defensive patterns

Strategy: validation

Validate before calling

def nul_free(v):
    return isinstance(v, str) and '\x00' not in v

Type guard

def is_nul_free(v: str) -> bool:
    return '\x00' not in v

Try / catch

from composio.exceptions import UnsafePathComponentError
try:
    p = secure_basename_join(base, name)
except UnsafePathComponentError:
    raise ValueError(f'malicious filename received: {name!r}')

Prevention

When it happens

Trigger: secure_basename_join(base, name) where name (or its extracted basename) contains '\x00' — e.g. 'file.txt\x00.jpg' trying to exploit NUL truncation in C-based syscalls.

Common situations: Adversarial filenames from untrusted API responses; binary garbage decoded into strings.

Related errors


AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/e81cf830545d0746. Report an issue: GitHub.