Summary
Two related vulnerabilities in tiktoken/load.py allow local cache poisoning of BPE tokenizer data on shared systems, potentially affecting tokenization integrity for all users on a multi-user machine.
Vulnerability 1: Cache Poisoning via Shared Temp Directory (CWE-377/CWE-379)
File: tiktoken/load.py (lines 45, 77)
Severity: MEDIUM (CVSS 5.5)
When no TIKTOKEN_CACHE_DIR environment variable is set, tiktoken caches downloaded BPE data in tempfile.gettempdir() + "/data-gym-cache" — typically /tmp/data-gym-cache/ on Linux systems.
The directory is created with os.makedirs(cache_dir, exist_ok=True) with no explicit permission restrictions. On multi-user Linux systems, /tmp is world-writable, meaning:
- A local attacker can pre-create
/tmp/data-gym-cache/ with permissive ACLs before any legitimate user runs tiktoken
- Cache filenames are predictable:
hashlib.sha1(url.encode()).hexdigest() (line 52)
- An attacker can compute the expected filename for any encoding (e.g.,
cl100k_base) and place a poisoned BPE file there
- Subsequent users loading the same encoding will read the attacker-controlled file
Proof of Concept
# As attacker on shared Linux system:
mkdir -p /tmp/data-gym-cache
python3 -c "
import hashlib
url = 'https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken'
print(hashlib.sha1(url.encode()).hexdigest())
"
# Output: predictable hash filename
# Write malicious BPE data to /tmp/data-gym-cache/<hash>
# As victim on same system:
import tiktoken
enc = tiktoken.get_encoding('cl100k_base') # Loads poisoned cache
enc.encode('sensitive text') # Produces attacker-controlled token IDs
Vulnerability 2: Optional Hash Verification Allows Silent Cache Tampering (CWE-345)
File: tiktoken/load.py (line 58)
Severity: MEDIUM (CVSS 5.3)
The cache loading logic contains:
if expected_hash is None or check_hash(data, expected_hash):
When expected_hash is None, cached files are loaded without any integrity verification. While OpenAI's built-in encodings supply hashes, third-party or custom encodings that call load_tiktoken_bpe() without providing a hash get zero protection against tampered cache files.
Combined with Vulnerability 1, this means poisoned cache files for custom encodings are silently accepted with no warning or error.
Impact
- Tokenization integrity: Poisoned BPE data produces incorrect token IDs, which could cause:
- Degraded model performance or nonsensical outputs
- Subtle data corruption in ML pipelines
- Potential for adversarial token manipulation in security-sensitive applications
- Scope: Any multi-user Linux system (CI/CD servers, shared dev machines, containers with shared
/tmp)
- For custom encodings: Complete bypass of integrity checks when hashes are not supplied
Suggested Fixes
- Use a user-specific cache directory by default (e.g.,
~/.cache/tiktoken via platformdirs or os.path.expanduser)
- Set restrictive permissions on the cache directory (e.g.,
0o700)
- Require hash verification or emit a warning when loading cache files without hash validation
- Use
tempfile.mkdtemp() or similar to create unique per-user temp directories if /tmp must be used
Reporter
Conner Webber (conner.webber000@gmail.com)
Summary
Two related vulnerabilities in
tiktoken/load.pyallow local cache poisoning of BPE tokenizer data on shared systems, potentially affecting tokenization integrity for all users on a multi-user machine.Vulnerability 1: Cache Poisoning via Shared Temp Directory (CWE-377/CWE-379)
File:
tiktoken/load.py(lines 45, 77)Severity: MEDIUM (CVSS 5.5)
When no
TIKTOKEN_CACHE_DIRenvironment variable is set, tiktoken caches downloaded BPE data intempfile.gettempdir() + "/data-gym-cache"— typically/tmp/data-gym-cache/on Linux systems.The directory is created with
os.makedirs(cache_dir, exist_ok=True)with no explicit permission restrictions. On multi-user Linux systems,/tmpis world-writable, meaning:/tmp/data-gym-cache/with permissive ACLs before any legitimate user runs tiktokenhashlib.sha1(url.encode()).hexdigest()(line 52)cl100k_base) and place a poisoned BPE file thereProof of Concept
Vulnerability 2: Optional Hash Verification Allows Silent Cache Tampering (CWE-345)
File:
tiktoken/load.py(line 58)Severity: MEDIUM (CVSS 5.3)
The cache loading logic contains:
When
expected_hashisNone, cached files are loaded without any integrity verification. While OpenAI's built-in encodings supply hashes, third-party or custom encodings that callload_tiktoken_bpe()without providing a hash get zero protection against tampered cache files.Combined with Vulnerability 1, this means poisoned cache files for custom encodings are silently accepted with no warning or error.
Impact
/tmp)Suggested Fixes
~/.cache/tiktokenviaplatformdirsoros.path.expanduser)0o700)tempfile.mkdtemp()or similar to create unique per-user temp directories if/tmpmust be usedReporter
Conner Webber (conner.webber000@gmail.com)