cybersecurity · beginner · ~15 min

Validate a token against a fixed character allowlist

Strict allow-list + length validation in a single pass.

Challenge

Accept a token only if its length is in range and every character is on a strict allowlist — the cheap pre-check that stops malformed tokens before they reach anything else.

Task

Implement int valid_token(const char *s, size_t min_len, size_t max_len) that returns 1 when all of these hold, and 0 otherwise:

  • s is non-NULL,
  • strlen(s) is within [min_len, max_len] (inclusive), and
  • every byte of s is in the allowlist [A-Za-z0-9_-].

Input

  • s: a NUL-terminated token the grader provides (may be NULL).
  • min_len, max_len: the inclusive length window.

Output

Returns 1 if s is valid, 0 otherwise.

Example

valid_token("abc123_XYZ-99", 8, 32)   ->   1
valid_token("short", 8, 32)           ->   0   (too short)
valid_token("has space here", 1, 64)  ->   0   (space not allowed)
valid_token("ok!", 1, 64)             ->   0   ('!' not allowed)
valid_token("", 0, 64)                ->   1   (empty allowed when min_len == 0)
valid_token(NULL, 0, 64)              ->   0

Edge cases

  • Empty string valid only when min_len == 0.
  • NULL pointer: return 0.
  • Length out of range: return 0 regardless of characters.

Rules

  • Use an allowlist, not a blocklist. Single pass, no allocations.

Why this matters

API keys, session tokens, and CSRF cookies look random to humans but follow strict rules (e.g. [A-Za-z0-9_-], 32-64 bytes). Validating that a token only contains allow-listed characters before passing it on to anything else is the cheapest defence against injection.

Input format

A NUL-terminated token s (may be NULL) and an inclusive length window min_len..max_len.

Output format

1 if s is in range and all characters are [A-Za-z0-9_-]; otherwise 0.

Constraints

Allowlist [A-Za-z0-9_-]; single pass; no allocations; guard NULL.

Starter code

#include <stddef.h>
int valid_token(const char *s, size_t min_len, size_t max_len) { /* TODO */ return 0; }

Common mistakes

Deny-listing (if (c == ';') return 0;) — infinite holes. Forgetting NULL guard.

Edge cases to handle

Empty input with min==0; min > max; NULL pointer.

Complexity

O(strlen).

Background lessons

Up next

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