
Python-инструмент для обнаружения PDF-файлов, эксплуатирующих CVE-2026-86950
Для получения дополнительного контекста о проекте и CVE-2026-86950 см. https://decalage.info/CVE-2026-86950/
Отказ от ответственности: большая часть этого readme и код обнаружения были написаны с помощью агентов ИИ для программирования. Инструмент был успешно протестирован на тысячах легитимных PDF-файлов и на доступном proof-of-concept, опубликованном здесь. Однако этот инструмент новый, а алгоритм обнаружения довольно сложен, поэтому используйте его с осторожностью.
detect_cve_2026_86950.py статически сканирует PDF-файлы на наличие встроенных шрифтов,
созданных для эксплуатации CVE-2026-86950 («The Great Glyph Grift») — записи
за границы буфера в растеризаторе глифов со сглаживанием Apple CoreGraphics
(исправлено в iOS / macOS 26.7.1).
Он никогда не отрисовывает шрифт и не выполняет какой-либо код эксплойта — он разбирает PDF и встроенную программу шрифта и ищет структурную сигнатуру атаки.
CoreGraphics преобразует координату устройства с плавающей точкой в целое число с фиксированной точкой 16.12 примерно так:
int32_t aa_double_to_fixed(double px) { return (int32_t)(0.5 + 4096.0 * px); }
Когда 4096 * px превышает диапазон int32, приведение типа является неопределённым поведением, и два места вызова (aa_moveto против aa_lineto) расходятся — одно насыщает, другое усекает. Это расхождение искажает вычисление ограничивающего прямоугольника глифа в aa_add_edges, поэтому буфер покрытия в aa_cache_render выделяется слишком малым, и растеризатор выполняет запись за границы. Патч 26.7.1 добавляет явное ограничение до ±0x3FFFF001.
Публичный proof-of-concept создаёт вредоносный шрифт TrueType, который вынуждает такую чрезмерно большую координату:
/Tf 1024) 4096 × device_coord переполняет int32./FontFile2) и CFF / OpenType (/FontFile3)./Tf, Tm), и проверяет, действительно ли 4096 × device_coord превышает INT32_MAX — то есть достижимо ли переполнение с фиксированной точкой.Вердикты: exploit (переполнение достижимо), suspicious (чрезмерная геометрия, но без переполнения при наблюдаемом размере), clean.
# with uv (recommended)
uv venv
uv pip install -r requirements.txt
# or any environment with pikepdf + fonttools
python3 detect_cve_2026_86950.py suspicious.pdf
python3 detect_cve_2026_86950.py -v *.pdf # per-font details
python3 detect_cve_2026_86950.py --json f.pdf # machine-readable
Код выхода: 0 — чисто, 1 — найден эксплойт/подозрительный код, 2 — ошибка.
aa_* в CoreGraphics, который отрисовывает как контуры TrueType glyf, так и CFF/Type2. Публичный PoC усиливает координаты с помощью составных глифов TrueType; шрифт CFF может напрямую достичь завышенных координат (например, путём накопления относительных операторов), поэтому анализируются как /FontFile2, так и /FontFile3. Эвристика составных цепочек специфична для TrueType; для CFF сигналом служит проверка на завышенные координаты / ложные границы (bounding-box-lie)./Tf, Tm) в потоках содержимого выполняется по мере возможности; оно не вычисляет полностью графическое состояние PDF / CTM. Если размер не найден, для проверки переполнения принимается консервативное значение по умолчанию 1024. Внутренние для шрифта сигналы завышенной геометрии от этого не зависят.