cybersecurity · beginner · ~15 min

Format String Specifier Sanitizer

Neutralize format string injection attacks by escaping format specifiers.

Challenge

Passing user-controlled strings directly into printf or syslog causes format string vulnerabilities where %n allows arbitrary memory writes and %x leaks stack memory. A sanitizer strips or escapes % specifiers.

Your Task

Implement:

int sanitize_format_string(const char *untrusted, char *dest, size_t dest_cap, size_t *escaped_count);

Rules

  1. If untrusted == NULL, dest == NULL, escaped_count == NULL, or dest_cap == 0, return -1.
  2. Initialize *escaped_count = 0.
  3. Copy characters from untrusted into dest.
  4. Whenever a % character is encountered in untrusted:
    • Write %% (two percent characters) to dest.
    • Increment *escaped_count by 1.
  5. If the sanitized string (including terminating NUL) exceeds dest_cap, return -1 without buffer overflow.
  6. On success: NUL-terminate dest and return 0.

Example

char out[32]; size_t count = 0;
sanitize_format_string("User %s score: 100%", out, sizeof(out), &count);
// out becomes: "User %%s score: 100%%", count == 2

Input format

untrusted: input string; dest: output buffer; dest_cap: capacity; escaped_count: count pointer.

Output format

Returns 0 on success, -1 on capacity overflow or NULL.

Constraints

Must escape every % into %%. Safe NUL termination.

Starter code

#include <stddef.h>

int sanitize_format_string(const char *untrusted, char *dest, size_t dest_cap, size_t *escaped_count) {
    (void)untrusted; (void)dest; (void)dest_cap; (void)escaped_count;
    return -1;
}

Common mistakes

Forgetting the NUL terminator; buffer overflow when double-percent exceeds dest_cap.

Edge cases to handle

Empty string produces empty output and 0 count; string with no % copied identically.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.