cybersecurity · intermediate · ~15 min · safe pentest lab
Apply bounded-copy + early failure on overflow.
Patch a deliberately vulnerable function that copies a string into a fixed buffer with no bounds check:
void render(const char *user_input, char *banner) {
strcpy(banner, "Welcome, ");
strcat(banner, user_input); // unbounded — overflows banner
}
Implement int render_safe(const char *user_input, char *banner, size_t banner_sz) that writes "Welcome, <user_input>" into banner without ever overflowing it.
user_input: a NUL-terminated string the grader passes.banner: the destination buffer.banner_sz: the size of banner in bytes.Returns 0 on success (with banner holding "Welcome, <user_input>"), or -1 if the full result would not fit. On overflow, banner is guaranteed NUL-terminated.
render_safe("Alice", buf, 32) -> 0, buf = "Welcome, Alice"
render_safe("Very Long User Name", buf, 12) -> -1, buf NUL-terminated
banner NUL-terminated.banner_sz == 0: return -1.snprintf) and detect truncation via its return value.Patching a deliberately vulnerable function teaches the diagnostic mindset: spot the unbounded write, audit the destination size, replace with a bounded equivalent. This is the daily work of security auditors.
A NUL-terminated user_input, a destination buffer banner, and its size banner_sz.
0 on success (banner = "Welcome, "); -1 on overflow (banner NUL-terminated).
Never write past banner_sz; always NUL-terminate; detect truncation.
#include <stdio.h>
#include <string.h>
int render_safe(const char *user_input, char *banner, size_t banner_sz) {
/* TODO */
return -1;
}
Replacing only the symptom (the obvious strcpy) without checking the rest of the function — overflows often come in pairs. Using strncpy (gotcha — doesn't NUL-terminate when source fits exactly).
Maximum-length input. Empty input. Input containing NUL bytes (rare in text, common in binary).
O(input length).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.