ZERO-UPLOAD SANDBOX
.webp Tier 1 · Deep AST Parser

WebP Image Container

RIFF-based modern raster image container supporting lossy (`VP8 `), lossless (`VP8L`), and extended alpha/animated/EXIF (`VP8X`) bitstreams.

CDN optimization proxies frequently transcode JPEGs into WebP on the fly while keeping `.jpg` URLs—causing desktop tools that trust file extensions to fail until Magic Bytes (`RIFF....WEBP`) are checked.

MIME Types image/webp
Byte Endianness little
Container Family riff
PRONOM PUID fmt/566
0xFF

Drop any .webp file (even 100 GB+) to inspect locally

Reads tiny File.slice() header/footer pages in a sandboxed Web Worker · 0 Bytes Uploaded

Binary Signature & Wire Layout

.webp Magic Bytes & Header Offset Map

Offset: 0x00 (0 B) ASCII: RIFF....WEBP
52 49 46 46 ?? ?? ?? ?? 57 45 42 50

'RIFF' + 4-byte LE chunk size + 'WEBP' FourCC

Byte Offset Length Data Type Field Name Engineering Description
0x00 - 0x03 4 B char[4] riff_magic ASCII 'RIFF'
0x04 - 0x07 4 B uint32_le riff_size File size minus 8 bytes
0x08 - 0x0B 4 B char[4] webp_fourcc ASCII 'WEBP'
0x0C - 0x0F 4 B char[4] first_chunk 'VP8 ', 'VP8L', or 'VP8X'
Upload Gateway & AppSec Advisory

.webp Security & Polyglot Risk Matrix

Risk Level: low
Arbitrary Code / Macros
NO (Inert Data)
Pickle Deserialization
SAFE (No Pickle VM)
XML External Entity (XXE)
NONE
Polyglot Prepend Risk
LOW (Strict 0x00 Magic)
Backend Upload Validation Recommendation

Keep libwebp patched (>= 1.3.2, post CVE-2023-4863 Huffman heap overflow) and check both 0x00=='RIFF' and 0x08=='WEBP'.

Compiler-Verified Reference Code

Read .webp Header & Metadata Without Heavy Dependencies

import struct, sys
with open(sys.argv[1], "rb") as f:
    riff, size, webp, chunk = struct.unpack("<4sI4s4s", f.read(16))
    assert riff == b"RIFF" and webp == b"WEBP"
    print(f"WebP ({chunk.decode().strip()}), riff_size={size}B")
CI/CD & Unit Test Fixtures

Deterministic .webp Sample Files & Edge Cases

Open Full .webp Sample Matrix & Mutator →
minimalexpect: valid

minimal-vp8x.webp

Real WebP encoded by libwebp via Pillow — RIFF/WEBP container with decodable VP8L/VP8 payload.

↓ Download (58 B)
SHA-256: 297ca327517d16217664fbb2ab4e878a676db57b3050a92b5ab929259266ffde
Exact: 58 bytes
curl -fsSL https://fileformat.co/fixtures/v1/webp/minimal-vp8x.webp -o minimal-vp8x.webp \
  && echo "297ca327517d16217664fbb2ab4e878a676db57b3050a92b5ab929259266ffde  minimal-vp8x.webp" | shasum -a 256 -c
realisticexpect: valid

og-banner-1200x630.webp

Real 1200×630 lossy WebP from Pillow at quality 85 for OpenGraph-dimension checks.

↓ Download (59.2 KB)
SHA-256: 1cf094696041edb5cd955bf546811c69b1e8cdd5092cdfd765300849e2ceee2d
Exact: 60,664 bytes
curl -fsSL https://fileformat.co/fixtures/v1/webp/og-banner-1200x630.webp -o og-banner-1200x630.webp \
  && echo "1cf094696041edb5cd955bf546811c69b1e8cdd5092cdfd765300849e2ceee2d  og-banner-1200x630.webp" | shasum -a 256 -c
edge-caseRIFF Size Mismatchexpect: parser_error

truncated-riff.webp

WebP truncated inside the image payload — declared RIFF size exceeds available bytes, Pillow must raise.

↓ Download (50 B)
SHA-256: 6b6b3468c2e38c48255de9164388e169324215d8fe802e113b1b109f631deee3
Exact: 50 bytes
curl -fsSL https://fileformat.co/fixtures/v1/webp/truncated-riff.webp -o truncated-riff.webp \
  && echo "6b6b3468c2e38c48255de9164388e169324215d8fe802e113b1b109f631deee3  truncated-riff.webp" | shasum -a 256 -c

Related Specifications & Alternatives