cybersecurity · beginner · ~15 min

Identify file type from the first bytes

Per-format magic-byte allow-list.

Challenge

Identify a file's type from its magic bytes — the second line of defence in an upload pipeline, after the (untrustworthy) extension.

Task

Implement int sniff_format(const unsigned char *buf, int len) that returns a format code based on the bytes at offset 0.

Format codes and their magic:

  • 1 = PNG: 89 50 4E 47 0D 0A 1A 0A (needs 8 bytes)
  • 2 = JPEG: FF D8 FF (needs 3 bytes)
  • 3 = GIF: GIF87a or GIF89a (needs 6 bytes)
  • 4 = PDF: %PDF- (needs 5 bytes)
  • 0 = unknown / not enough bytes

Input

  • buf: the first bytes of a file (the grader passes fixed buffers); may be NULL.
  • len: the number of valid bytes in buf.

Output

Returns int: the format code (0..4). Each magic must match at exactly offset 0.

Example

{0x89,'P','N','G',0x0D,0x0A,0x1A,0x0A} (len 8)   ->   1
{0xFF,0xD8,0xFF,0xE0,...} (len 6)                ->   2
{'G','I','F','8','9','a'} (len 6)                ->   3
{'%','P','D','F','-',...} (len 8)                ->   4
{0x12,0x34,0x56,0x78} (len 4)                    ->   0
buf NULL, or PNG buffer with len 3               ->   0

Edge cases

  • NULL buffer returns 0.
  • A buffer shorter than a format's required length cannot match that format.
  • The magic must be at offset 0, not anywhere in the buffer.

Rules

  • Bound-check len before reading; never index past buf[len-1].

Why this matters

Upload pipelines that trust the file extension get owned. Magic-byte sniffing is the second line of defence.

Input format

A byte buffer buf (or NULL) and its valid length len.

Output format

An int format code: 1=PNG, 2=JPEG, 3=GIF, 4=PDF, 0=unknown/too short.

Constraints

Match each magic at offset 0; bound-check len before indexing.

Starter code

int sniff_format(const unsigned char *buf, int len) { /* TODO */ (void)buf; (void)len; return 0; }

Common mistakes

Matching PDF anywhere instead of at offset 0.

Edge cases to handle

Very short buffer; len < 4.

Complexity

O(1).

Background lessons

Up next

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