Метаданные PDF и скрытые данные
Последнее обновление:
Метаданные документа — это информация, которую файл несёт о себе самом помимо содержимого страницы: кого его поля называют автором, какое приложение его создало, когда он, по его словам, был создан и изменён, и какой прежний материал ещё находится внутри. PDF может содержать две перекрывающиеся системы метаданных, цепочку прежних ревизий, полные вложенные файлы и текст, отрисованный невидимо; фотография JPEG содержит дневник камеры; даже простой снимок PNG называет программу, которая его сделала. Эта статья проходит по каждому из этих укрытий, объясняет, почему данные переживают обычное редактирование, и как происходили реальные утечки. Чтобы проверить собственный файл по ходу чтения, запустите инструмент криминалистики документов — он работает локально в вашем браузере, — а сторону структуры чтения тех же файлов смотрите в статье ваши PDF — часть доступности вашего сайта.
Внутри каждого PDF едут две системы метаданных
Более старая из двух — информационный словарь, небольшой набор пар ключ–значение, хранящийся в трейлере файла: Title, Author, Creator (приложение, создавшее исходный документ), Producer (приложение, создавшее PDF), CreationDate и ModDate. Эти поля записываются автоматически при экспорте, и большинство авторов документов никогда не открывает диалог свойств, который бы их показал, — именно поэтому они утекают. Отчёт, экспортированный с личного ноутбука, несёт имя учётной записи этого ноутбука как автора. Документ, начатый с прошлогоднего шаблона, всё ещё называет прошлогоднего автора. Ничего из этого не видно на напечатанной странице, и всё это находится в одном диалоге свойств от каждого получателя файла.
Более новая система — XMP, XML-пакет, встроенный в документ, построенный на расширяемой платформе метаданных Adobe и описанный вместе с самой спецификацией PDF, ISO 32000-2. XMP повторяет большую часть той же территории в пространствах имён: dc:title для заголовка, pdf:Producer, xmp:CreateDate и xmp:ModifyDate, плюс поля, которых у старого словаря никогда не было, например инструмент создания. Наличие двух систем было бы безвредно, если бы их держали в ногу, но их не держат: один инструмент обновляет информационный словарь и игнорирует XMP, другой переписывает XMP и оставляет словарь устаревшим, третий удаляет одно и сохраняет другое. В результате один файл обычно рассказывает о себе две слегка разные истории — и само несогласие является информацией, потому что оно записывает, что более чем один инструмент, в более чем один момент, прикасался к документу.
Инкрементные обновления: удалённый абзац, который никогда не ушёл
PDF был спроектирован для редактирования только добавлением. Когда редактор сохраняет изменение инкрементно, он не переписывает файл: он добавляет изменённые объекты, новую секцию перекрёстных ссылок и новый трейлер в конец, связываясь с предыдущим трейлером указателем /Prev. Каждая ревизия заканчивается собственным маркером %%EOF, поэтому подсчёт этих маркеров даёт нижнюю границу того, сколько раз файл сохранялся таким образом, — и каждая прежняя ревизия остаётся физически присутствующей и читаемой в байтах. Откройте такой файл в обычном просмотрщике — и вы увидите только самую новую ревизию. Прочитайте байты или пройдите по цепочке назад — и прежнее состояние документа всё ещё там: старое число в таблице, прежняя формулировка пункта, абзац, удалённый перед публикацией.
Это механизм, стоящий за неудачами закрашивания, которые продолжают попадать в новости. Команде нужно опубликовать отчёт с удержанными именами или цифрами, поэтому кто-то рисует чёрные прямоугольники поверх чувствительных мест — операцию рисования, которая меняет вид страницы и не трогает ничего под ней, — или удаляет текст в редакторе, который затем сохраняет инкрементно, оставляя удалённые объекты в прежней ревизии. Опубликованный файл выглядит чистым. Несколько дней спустя читатель выделяет «закрашенную» область, копирует её и вставляет исходные слова в текстовый редактор; или исследователь разбирает цепочку ревизий и восстанавливает удалённое. Настоящее закрашивание — другая операция, чем покрытие: подлежащее содержимое должно быть удалено из потока содержимого, а файл полностью переписан, чтобы сами байты больше не содержали того, что страница больше не показывает. Если файл, который вы собираетесь опубликовать, несёт несколько маркеров %%EOF, его история всё ещё внутри — исходите из того, что мотивированный читатель эту историю прочитает.
Вложенные файлы и скрытый текст: груз, который никто не перечисляет
PDF может нести полные файлы внутри себя. Формат определяет дерево имён вложенных файлов, к которому ведут объекты /EmbeddedFiles и /Filespec, и инструменты авторства используют его для исходных таблиц, приложений данных и портфельных документов. Панель вложений, которая бы их раскрыла, — это панель, которую большинство читателей никогда не открывает, поэтому вложенный груз путешествует молча: опубликуйте отполированную сводку в PDF — и вы, возможно, опубликуете и рабочую таблицу за ней, в комплекте с её собственными метаданными, черновыми листами и комментариями. Обратное верно и для получателей: вложение внутри полученного PDF наследует доверие окружающего его документа, и именно поэтому вложенные файлы заслуживают строки в любом контрольном списке проверки, а не открытия случайно.
Текст может скрываться, не будучи отдельным файлом. PDF рисует текст в режиме отрисовки, а режим 3 — устанавливаемый оператором 3 Tr — не рисует ни заливку, ни контур: символы находятся в потоке содержимого, их можно выделять, искать и извлекать, и они полностью невидимы на странице. Часть невидимого текста законна и ценна: слой OCR за отсканированной страницей — это именно оно, скрытый текст, делающий изображение доступным для поиска. Проблема — всё остальное, что оказывается в режиме 3 или у его родственников: белый текст на белом фоне, текст, обрезанный за пределы видимой страницы, слой ключевых слов, добавленный для поисковых систем, — потому что читатель, извлекающий текстовый слой, получает слова, которых страница никогда не показывала. Когда скрытый слой не согласен с видимым, файл говорит две вещи одновременно, и только одна из них была вычитана.
Изображения тоже ведут дневники: блоки PNG и Exif в JPEG
Файл PNG — это последовательность именованных блоков, и несколько типов блоков существуют только для того, чтобы нести текст: tEXt, его сжатый брат zTXt и интернационализированный iTXt. Инструменты экспорта пишут их по привычке — ключевое слово Software, называющее редактор, строку инструмента создания, иногда целый встроенный XML-профиль, — и они переживают каждую обрезку и каждое изменение размера, оставляющие список блоков нетронутым. Блок tIME добавляет метку последнего изменения, блок eXIf может нести полный блок метаданных камеры, а байты, добавленные после закрывающего блока IEND, игнорируются любым просмотрщиком, оставаясь в файле. Снимок экрана, который выглядит как нейтральная картинка окна, может поэтому назвать программное обеспечение машины, датировать сам себя и нести данные, которых его автор никогда не видел.
Фотографии JPEG идут дальше. Файл — это цепочка сегментов маркеров: APP0 несёт заголовок JFIF, APP1 несёт либо блок Exif, либо пакет XMP — иногда оба. Поля IFD0 в Exif читаются как дневник камеры: Make и Model устройства, DateTime, когда фотография была сделана или последний раз изменена, Software, обработавшее её, и, в расширенных каталогах, координаты GPS. Фотографии с телефона, опубликованные прямо из фотоплёнки, ставили организации и частных лиц в неловкое положение, точно помещая их во время и место, которых сама фотография никогда не показывала. Сегменты комментариев (COM) добавляют свободный текст от последнего инструмента, сохранявшего файл, лишние байты могут оставаться после маркера конца изображения, а инструмент, который читает всё это, — ExifTool Фила Харви, указанный в источниках, — это бесплатная загрузка, что означает, что ваши получатели тоже могут его прочитать.
Сверьте метки времени, затем очистите перед публикацией
Одна метка времени — это утверждение; несколько меток времени — это история, которую можно сверить с самой собой. Дата создания, выпадающая после даты изменения, не может описывать документ, произведённый одним инструментом за один проход. Дата из информационного словаря, не согласующаяся с датой XMP для того же события, записывает два инструмента с двумя часами. Дата в будущем записывает неверно установленные часы, поле, отредактированное вручную, или файл, собранный из кусочков. Даже сам формат даты PDF приглашает к неоднозначности: строка D: может опускать свой часовой пояс, оставляя читателям гадать, с каких часов пришли числа. Относитесь к каждому несоответствию так, как аудитор относится к расхождению в книге: у него обычно есть невинное объяснение — повторное использование шаблона, часы ноутбука, оптимизатор, переписавший файл при загрузке, — и это доказательство, которое нужно взвесить, а не приговор сам по себе. Поля метаданных может отредактировать любой, у кого есть бесплатные инструменты, поэтому они подкрепляют историю или противоречат ей; доказать её они не могут.
Очистка — это, следовательно, рабочий процесс, а не кнопка. Во-первых, проверьте: пропустите файл через инструмент криминалистики документов и запишите, что он сказал бы незнакомцу, — имена автора и инструментов, число ревизий, вложенные файлы, скрытый текст, метки времени, спорящие друг с другом. Во-вторых, исправляйте у источника, где можете: исправляйте свойства документа в приложении авторства, а не латайте его вывод. В-третьих, экспортируйте свежую, полную перезапись — печать в PDF, специализированный очиститель или ExifTool для изображений, — потому что полная перезапись отбрасывает прежние ревизии, осиротевшие объекты и лишние данные так, как инкрементное сохранение никогда не сделает. Наконец, повторно проверьте копию, которую вы действительно отправляете, а не ту, которую собирались отправить. И сохраняйте различие, на котором держится вся статья: внутренние оригиналы должны сохранять свои метаданные, потому что происхождение, архивная ценность и даже доступность — заголовок документа тоже метаданные — зависят от этого. Очищайте публикуемую копию и сохраняйте запись нетронутой дома.