Undefined Behavior & Safety

the trust boundary and untrusted input

Think of a building's front desk. Inside, among colleagues, you assume good intentions; at the front door, where strangers arrive, you check badges and IDs. The line between 'inside, assumed safe' and 'outside, must be checked' is the trust boundary. Every program has one, and a great deal of security comes down to knowing exactly where it lies and being disciplined about everything that crosses it.

A trust boundary is the line that separates code and data you control from code and data that comes from somewhere you do not — a file the user chose, text typed at a prompt, bytes arriving over a network, a command-line argument, an environment variable, the contents of a request from another program. Anything that crosses INTO your program from the outside is untrusted input: you must assume it may be malformed, oversized, malicious, or specifically crafted to break you. The whole set of places where untrusted input can enter is your attack surface. The defensive move is to validate at the boundary — check sizes, ranges, formats, and pointers right where the data arrives — and to treat data as trusted only AFTER it has passed those checks. The dangerous mistake is to carry unvalidated input deep into the program and only discover its badness when it overflows a buffer or indexes out of bounds far from where it entered.

Why this matters: nearly every famous security breach is a story of untrusted input crossing a trust boundary without proper checking — an overly long name smashing a stack buffer, a length field the attacker controls driving an out-of-bounds copy, a format string supplied by the user. In C the stakes are highest because there is no automatic protection: an unchecked length from outside becomes a buffer overflow, and a buffer overflow becomes a takeover. The practical discipline is to draw the boundary consciously, name the inputs that cross it, and validate every one of them at the crossing — full security hardening goes further (and is a Volume II topic), but correctness at the trust boundary is where it begins, because here a security hole is simply the visible consequence of a correctness bug.

/* untrusted: a length field read from the network */ uint32_t len = read_u32(socket); /* attacker controls this */ if (len > MAX_PAYLOAD) return -1; /* validate AT the boundary */ char *buf = malloc(len); if (buf == NULL) return -1; read_exact(socket, buf, len); /* only now is len trusted */

A length supplied by a remote peer is untrusted; validating it against a maximum right at the boundary stops an attacker-chosen size from driving a huge or overflowing allocation.

Validate input AT the boundary, before it travels deeper — once unvalidated input flows into the program, a later overflow appears far from where the data entered and is much harder to trace. Full security hardening is a Volume II topic; correctness at the boundary is where it starts.

Also called
trust boundaryuntrusted inputattack surface信任邊界不受信任的輸入