Information Security
14 March 2019

Как браузер помогает товарищу майору

Знаете, когда я почти нечаянно обнаружил, читая прекрасную книгу Дмитрия Кетова «Внутреннее устройство Linux» (и это не реклама), что каждый скачанный нами файл из Интернета с легкой руки браузера оставляет в расширенных атрибутах файла (в inode файла, не в самом файле) как минимум полную ссылку на то откуда он был скачан, я пришел в легкое возбуждение и хотел тут же броситься спасать мир. Позже, немного изучив этот вопрос, почитав «коммиты» и «комменты», говорившие, что этой возможности, встроенной в ядро GNU/Linux, как минимум уже около 10 лет, что ею пользуется не только браузеры, но и, к примеру, популярная утилита wget (curl нет), и что эта вещь считается чуть ли не нормой в Linux (и, как выяснилось позже, в MacOS), то я немного подуспокоился. Одно не давало мне покоя: поиск ключевого слова getfattr в google по сайту «Хабра»: site:https://habr.com getfattr, равно как и по ЛОРУ: site:https://linux.org.ru getfattr ничего толком не дал. «Значит» — подумал я — «эта тема еще особенно не обсуждалась». — Что же, тогда пришло время ее обсудить, но для начала пришлось немного по-исследовать. И вот что я обнаружил:

image

Дисклеймер*. Из-за отсутствия времени буду добавлять много букв по мере возможности. Пока только конкретика.

Да, каждый скачанный файл с помощью любого Chromium-совместимого браузера (проверено в lxc-контейнере на Chrome, Chromium, Yandex и последней Opera) записывает в расширенных атрибутах файла, спрятанных в недрах файловой системы, вот такой вывод:

i@ars:~$ getfattr -d logo.png 
# file: logo.png
user.xdg.origin.url="https://habr.com/images/logo.png"
user.xdg.referrer.url="https://habr.com/images/logo.png"

При этом все они честно ничего не пишут, если вы скачиваете файл в режиме «инкогнито» / «private browsing»

Знали ли вы об этом? Если да, то хорошо. Если нет, то теперь будете знать. Что касается Firefox и Palemoon — эти парни честно игнорируют эту помощь товарищу майору. Весь букет программ для просмотра Интернет-страниц я не проверял, но думаю, все, что основано на Chromium делает это, остальные скорее нет.

Теперь о MacOS и Windows. В «макоси» данная функция также работает в Chrome:

iMac-Igor:~ [censored]$ xattr -l habr_logo.png 
com.apple.metadata:kMDItemWhereFroms:
00000000  62 70 6C 69 73 74 30 30 A2 01 02 5F 10 20 68 74  |bplist00..._. ht|
00000010  74 70 73 3A 2F 2F 68 61 62 72 2E 63 6F 6D 2F 69  |tps://habr.com/i|
00000020  6D 61 67 65 73 2F 6C 6F 67 6F 2E 70 6E 67 5F 10  |mages/logo.png_.|
00000030  20 68 74 74 70 73 3A 2F 2F 68 61 62 72 2E 63 6F  | https://habr.co|
00000040  6D 2F 69 6D 61 67 65 73 2F 6C 6F 67 6F 2E 70 6E  |m/images/logo.pn|
00000050  67 08 0B 2E 00 00 00 00 00 00 01 01 00 00 00 00  |g...............|
00000060  00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00  |................|
00000070  00 00 00 51                                      |...Q|
00000074
com.apple.quarantine: 0001;5c8a21e7;Google Chrome;26D6C537-E6B0-4715-9E77-656FF1C5B7A9

… работает она и в Safari. В FF не проверял, но полагаю, что прекраснодушный Firefox для MacOS также лишен этой «привилегии», как и в Linux.

Утверждается, что это фича используется для определения файла «скаченного из Интернет» и именно по наличию этого атрибута в «макоси» выскакивает предупреждение об опасности запуска и т.п. Хм… Странно… Но здесь мы плавно перейдем к Windows.

«Венда» вещь безусловно бездарная и следящая за всеми с неприкрытым цинизмом. (чего только стоят неотключаемые обновления в W10! ). В ней, в NTFS также спрятаны лазейки для записывания чего угодно в расширенные атрибуты файлов. Называются они streams и могут все то же самое. Говорят, что в эти припрятанные файловой системой «потоки» периодически любят что-нибудь да записывать вирусы, поскольку все остальные программы их используют редко. Не могу ничего сказать, я Windows последние 10 лет не пользуюсь. И все же. При первом приближении в Win10 я не обнаружил подобной «мелочи», а именно того факта, чтобы в расширенный атрибуты NTFS Google Chrome писал ссылки подобно тому, как он делает это в Linux и MacOS. Оговорюсь: это при первом приближении, поскольку утверждается, что у streams есть как-бы несколько слоев и не все они прямо доступны.

Вот так, если кратко, обстоит дело с тем, как устроены не только браузеры, но и файловые системы при предельно кратком рассмотрении.

Я еще буду править эту статью. Но заранее прошу отказаться от комментариев в виде: «Ну и что, мне нечего скрывать». В общем, нам всем, как-правило, тоже. Но наиболее рьяным «намнечегоскрывать», если таковые найдутся, я могу посоветовать включить встроенную камеру и микрофон, и дать публичную ссылку здесь, в комментариях, чтобы и мы все могли в этом убедиться. Шутка конечно.

Вот такие шуточки.

UPD*
Итак. Что выясняется, благодаря вашим многочисленным комментам и дополнительному изучению материала:

Во всех трех операционных системах: Linux, MacOS и Windows браузеры, в первую очередь Chrome и Chromium-based, пишут путь на источник скачанных файлов на уровне файловой системы.

В Linux'e браузеры на базе Google Chrome пишут полную ссылку на исходное местоположение файла в поля: user.xdg.origin.url и user.xdg.referrer.url
Делается это с использованием фичи ядра Linux, которая появилась в нем еще аж с 2002 года в виде расширенных атрибутов файла под общим названием xattr[Wikipedia], которые доступны почти во всех популярных FS: ext2, ext3, ext4, Squashfs, ReiserFS, XFS, Btrfs, ZFS. Опциями ядра или флагами монтирования поддержку расширенных атрибутов можно отключить, но она используется при контейнеризации (атрибуты для namespaces), SELinux-ом и используется «Иксами» в тех или иных случаях с легкой руки freedesktop.org (например, для определения MIME type файла) [ссылка].

Используются эти поля и некоторыми программами. Как, например, указанными выше в статье браузерами Chrome, Chromium, Yandex, Opera, в некоторых случаях Firefox'ом и консольной утилитой wget, а также, судя по Википедии: curl, Beagle, OpenStack Swift, Dropbox, KDE. По утверждениям в комментариях wget последней версии 1.20.1 не пишет уже (у меня 1.19 — пишет, также не пишет у меня и curl, а судя по wiki — должен). По-видимому, среди разработчиков периодически проходит дискуссия включать или не включать подобную фичу в очередной релиз ). В Firefox для Linux, как я проверял, ничего не сохраняется, а вот для MacOS и Windows, как проверили другие — да. Не исключено, что это как-то связано с политикой самих ОС от Apple и Microsoft.

Вообще, ограничений по созданию и управлению полями расширенных атрибутов в Linux нет. Вы сами можете создавать и записывать в расширенные атрибуты информацию, какую хотите. На уровне ядра ограничения такие: 255 байт для имени и до 64KB для значения поля. У некоторых файловых систем они такие (XFS and ReiserFS), у других они меньше (ext2/3/4 и btrfs).

Похожая ситуация в MacOS и Windows с их FS HFS+ и NTFS. С той лишь разницей, что подобные атрибуты по-разному называются, прячутся и показываются. В Ubuntu 18.10 вы не увидите их в дефолтном файловом менеджере Nautilus как и в консоли, пока не установите пакет attr, включающий утилиты просмотра и установки attr-атрибутов (getfattr и setfattr соотвественно). На Маке увидеть можно либо в Finder по cmd+I, либо при помощи встроенной xattr. В Windows, говорят, в свойствах файла виден лишь флаг наличия спрятанной ссылки у файла (руки не дошли проверить где), либо через powershell или программу streams:

victoriously:
 Здесь некто советует помимо powershell использовать программу streams. Субъективно удобнее.
streams [-s] [-d] <файл или каталог>


В комментариях много вариантов ухода от записи информации или удаления ссылок на файлы для той или иной операционной системы. Например, для Linux мне понравилась простая идея монтировать в папку, куда будут загружаться файлы браузером в другой файловой системе — без флага записи расширенных атрибутов по-умолчанию. Например, в ReiserFS --> оригинал коммента

Идея с отключением атрибутов вообще на этапе монтирования в /etc/fstab
mount -o nouser_xattr

во-первых, не отменят уже имеющиеся поля, но главное, как мне кажется, чревата нарушением работы ряда служб (SELinux, LXC). (--> полный комментарий)

Наиболее простым способом является чистка командой/скриптом в консоли или в powershell:

Linux:
setfattr -hx user.xdg.origin.url имя_файла

оригинал комментария

MacOS:
xattr -c -r ~/Downloads

оригинал комментария

Windows:
get-childitem «D:\Downloads\» | unblock-file

оригинал комментария

Общий итог:
Появившаяся достаточно давно (в Linux c 2002 года) возможность приписывать к файлу любые поля и заполнять их значениями, начала реализовываться в виде записывания полного пути на источник скачивания довольно недавно. Где-то после 2015-2016 гг. Так, например, у меня на Маке остались файлы с 2015 года, скачанные из Сети и (версия 10.6.8) и никаких ссылок мною обнаружено не было. Кто-то из комментаторов проверял на предыдущих версиях Debian (8-рка) и тоже ничего не обнаружил. ссылка на коммент.

Когда это появилось в Windows — нет сил выяснять, но судя по этому комментарию, функцию «принесли» не только в W10 и W7, но даже в W_XP ;)

Повторю простую мысль: Странно не то, что это есть, странно, что это появилось тихо и везде почти незаметно. Именно поэтому, в последней версии утилиты для скачивания файлов в Linux wget бывшую там фунцию сохранения ссылки убрали:

* Changes in Wget 1.20.1

** --xattr is no longer default since it introduces privacy issues.


ссылка на коммент

Ибо, как мне кажется, такие вопросы должны контролировать и решать мы — пользователи.

Уф.

UPDATE 2
В Chromium под Linux сохранение user.xdg.origin.url и user.xdg.referrer.url в xattrs более производится не будет.
chromium-review.googlesource.com/c/chromium/src/+/1407441

+227
137k 471
Comments 321