cybersecurity · intermediate · ~15 min · safe pentest lab

Audit format string for dangerous specifiers

Identify and block format string vulnerabilities and memory write primitives before logging.

Challenge

Format string vulnerabilities occur when untrusted user input is passed as the format argument to printf() or syslog(). The %n specifier allows arbitrary memory writes, while %s, %x, and %p leak sensitive memory.

Your Task

Implement:

int audit_format_string(const char *fmt);

Audit fmt for format specifiers.

Rules

  1. If fmt == NULL, return -1.
  2. Literal escaped percent signs (%%) are safe.
  3. If any %n specifier (including length variants like %ln, %lln, %hn) is found, return -2 (critical memory write attempt).
  4. If any other unescaped format specifier (%s, %d, %p, etc., or a trailing lone %) is found, return -1 (untrusted specifier).
  5. If the string contains no format specifiers or only safe %% escapes, return 0.

Example

audit_format_string("User login: alice"); // returns 0 (safe)
audit_format_string("Progress: 100%%");   // returns 0 (safe escaped)
audit_format_string("Value: %d");       // returns -1 (untrusted format)
audit_format_string("Exploit: %08x%n"); // returns -2 (critical %n)

Input format

fmt: NUL-terminated format string to inspect.

Output format

Returns 0 if safe, -1 if untrusted specifiers present, -2 if critical %n found.

Constraints

C11 freestanding string scanning. Read-only inspection.

Starter code

/* Audit fmt for format specifiers.
   Returns 0 if safe (no unescaped specifiers),
   -1 if any unescaped specifier is present,
   -2 if critical %n write specifier is found,
   -1 if fmt is NULL. */
int audit_format_string(const char *fmt) {
    (void)fmt;
    return -1;
}

Common mistakes

Skipping past %% incorrectly; not prioritizing %n over general specifier return.

Edge cases to handle

Multiple %%; %n after other specifiers; lone trailing % at end of string; empty string returns 0.

Background lessons

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