Secure Coding in C · intermediate · ~12 min

Base64 and tokens — decode before you trust

Decode base64 safely and validate a JWT's structure before trusting it.

Overview

Bounded base64 decoding + structural JWT validation (three base64url segments), plus why alg:none is dangerous.

Why it matters

You decode untrusted tokens constantly; doing it with bounds checks and shape validation stops a whole class of auth bugs.

Lesson

Why this matters

Tokens, certificates, and payloads travel as base64. Before you can reason about a JWT or a cert, you have to decode it — and decoding untrusted input is exactly where bounds bugs creep in.

Base64, briefly

Every 4 characters encode 3 bytes. = is padding (1 or 2 at the very end). A safe decoder rejects bad characters, padding in the middle, and any output that would overflow the caller's buffer.

JWT structure

A JWT is three base64url segments: header.payload.signature. base64url swaps +/ for -_ and drops =. Before verifying a signature you confirm the shape — exactly three non-empty segments of base64url characters.

The alg:"none" trap

A JWT header can claim alg:"none", meaning "no signature." Libraries that honoured this let attackers forge tokens. Structural validation is step one; never accept alg:none for a token you're meant to verify.

Your job (two exercises)

  • b64_decode(...) — a bounded base64 decoder.
  • jwt_is_wellformed(...) — structural JWT check (3 base64url segments).

What this is NOT

  • A crypto verifier — we check encoding and shape, not signatures.

Summary

4 chars → 3 bytes with strict validation; a JWT is 3 non-empty base64url parts; never trust alg:none.

Practice with these exercises