schollz/croc · error · Error
A remote path contains a null byte
Error message
A remote path contains a null byte
What it means
cleanSegments() sanitizes every remote path coming from the peer's transfer offer. A NUL byte in a path is never legitimate and is a classic trick against path-based filesystems and logging pipelines, so it is rejected outright before any segment splitting.
Source
Thrown at web/src/protocol/metadata.ts:11
import { base64ToBytes } from "./bytes";
import type {
OfferedFile,
SenderInfoWire,
TransferOffer,
WireFileInfo,
} from "./types";
function cleanSegments(value: string) {
const replaced = value.replaceAll("\\", "/");
if (replaced.includes("\0")) throw new Error("A remote path contains a null byte");
const segments: string[] = [];
for (const segment of replaced.split("/")) {
if (segment === "" || segment === ".") continue;
if (segment === "..") throw new Error(`Remote path escapes the destination: ${value}`);
if ([...segment].some((character) => !/\P{C}/u.test(character))) {
throw new Error(`Remote path contains a non-printable character: ${value}`);
}
segments.push(segment);
}
return segments;
}
export function normalizeFolder(value = ".") {
if (/^(?:[a-zA-Z]:|\/)/.test(value)) {
throw new Error(`Remote path must be relative: ${value}`);
}
const segments = cleanSegments(value);
const normalized = segments.join("/") || ".";View on GitHub (pinned to e25f1bdc04)
Solutions
- Reject or terminate the transfer from the offending peer — the metadata is malformed or malicious; there is no safe reinterpretation.
- If you are the sender side, strip NUL bytes from paths before building the offer.
- When fuzzing, treat this as an expected rejection, not a crash: wrap validateSenderInfo in try/catch and assert the error message.
Defensive patterns
Strategy: validation
Validate before calling
function hasNoNullByte(path: string): boolean {
return !path.includes("\0");
}
// before validating an offer:
if (!hasNoNullByte(wire.fr ?? ".") || !hasNoNullByte(wire.n ?? "")) {
rejectOffer("null byte in remote path");
} Try / catch
try {
const offer = validateSenderInfo(info);
} catch (error) {
if (error instanceof Error && error.message === "A remote path contains a null byte") {
abortTransfer(); // hostile/malformed peer metadata; do not continue
}
throw error;
} Prevention
- Treat remote path metadata as untrusted input; validate before persisting or displaying it.
- Never log raw remote paths to systems that treat NUL as a terminator.
- In fuzz suites, assert NUL-containing paths are rejected.
When it happens
Trigger: A received SenderInfo offer where a file's folder (fr), name (n), or an EmptyFoldersToTransfer entry contains '\0' — e.g. crafted by a hostile sender ("file.sh\0.txt") or produced by a mis-encoding peer.
Common situations: Security review / fuzzing of the receive path; a peer running on a system that allows NUL in filenames passed through verbatim; hostile sender attempting path-confusion attacks against the browser download sink.
Related errors
- Remote path escapes the destination: ${value}
- Remote path contains a non-printable character: ${value}
- Remote path must be relative: ${value}
- Remote path is not allowed: ${value}
- Remote filename must be a basename: ${nameValue}
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/77c43fbf8304c602.
Report an issue: GitHub.