Безопасное использование временных файлов

В моей программе есть статическая библиотека, которая может принимать в качестве входных данных только имена файлов, а не содержимое файла. Я ничего не могу поделать с исходным кодом библиотеки. Поэтому я хочу: создать новый файл, сохранить данные для обработки в нем, записать его на диск (?), Передать его имя в библиотеку, а затем удалить его.

Но я также хочу, чтобы этот процесс был довольно безопасным:
1) файл должен быть созданным заново, без каких-либо поддельных данных (возможно, это не критично, но что угодно);
2) кто-нибудь, кроме моего процесса не должен быть в состоянии читать или писать из / в этот файл (я хочу, чтобы библиотека обрабатывала мой реальные данные, а не фиктивные данные, которые каким-то мудрецам удалось подключить);
3) после того, как я закончу с этим файлом, это должен быть удаленным (хорошо, если кто-то TerminateProcess() мне, наверное, особо ничего не поделаешь, но все же).

Библиотека, кажется, использует не Unicode fopen() чтобы открыть данный файл, так что я не совсем уверен, как справиться со всем этим, так как программа предназначена для работы в Windows. Какие-либо предложения?

6

Решение

У вас уже есть много предложений, но я не упомянул еще один вариант — использование именованных каналов. Это будет зависеть от рассматриваемой библиотеки относительно того, работает ли она или нет, но, возможно, стоит попробовать. Вы можете создать именованный канал в вашем приложении, используя CreateNamedPipe и передайте имя канала в библиотеку для работы (имя файла, которое вы передадите, будет \\. \ Труба \ PipeName). Примет ли библиотека такое имя файла или нет — это то, что вы должны попробовать, но если это работает, преимущество заключается в том, что ваш файл никогда не должен быть записан на диск.

4

Другие решения

Это может быть достигнуто с помощью CreateFile а также GetTempFileName функции (если вы не знаете, можете ли вы записать в текущий рабочий каталог, вы также можете использовать, GetTempPath).

  1. Определите каталог для хранения вашего временного файла; текущий каталог («.») или результат GetTempPath были бы хорошими кандидатами.
  2. использование GetTempFileName создать временное имя файла.
  3. Наконец, позвоните CreateFile создать временный файл.

На последнем шаге нужно учесть несколько вещей:

  • dwFlagsAndAttributes параметр CreateFile должно включать FILE_ATTRIBUTE_TEMPORARY,
  • dwFlagsAndAttributes параметр, вероятно, должен также включать FILE_FLAG_DELETE_ON_CLOSE чтобы убедиться, что файл будет удален, несмотря ни на что (это, вероятно, также работает, если ваш процесс падает, и в этом случае система закрывает все дескрипторы для вас).
  • dwShareMode параметр CreateFile должно быть FILE_SHARE_READ так что другие попытки открыть файл будут успешными, но только для чтения. Это означает, что код вашей библиотеки сможет прочитать файл, но никто не сможет записать в него.
2

Эта статья должен дать вам несколько хороших рекомендаций по этому вопросу.

Суть дела в следующем:

  • POSIX mkstemp () функция является безопасным и предпочтительным решением, если оно доступно. К сожалению, он недоступен в Windows, поэтому вам нужно будет найти оболочку, которая правильно реализует эту функцию с помощью вызовов Windows API.
  • В Windows tmpfile_s () Функция — единственная, которая фактически открывает временный файл атомарно (вместо простого создания имени файла), защищая вас от состояния гонки. К сожалению, эта функция не позволяет указать, в каком каталоге будет создан файл, что является потенциальной проблемой безопасности.
1

Прежде всего, вы можете создать файл во временной папке пользователя (например, C: \ Users \\ AppData \ Local \ Temp) — это идеальное место для таких файлов. Во-вторых, когда создание файла, Вы можете указать, какой тип доступа вы предоставляете.

Фрагмент справочной страницы CreateFile на MSDN:

dwShareMode

  • 0 Запрещает другим процессам открывать файл или устройство
    если они запрашивают удаление, чтение или запись.
  • FILE_SHARE_DELETE Позволяет последующим операциям открытия файла или устройства
    запрос на удаление доступа. В противном случае другие процессы не смогут открыть файл или устройство, если они
    запрос на удаление доступа. Если этот флаг не указан, но файл или устройство были открыты для доступа для удаления, функция завершается ошибкой. Примечание. Доступ к удалению позволяет выполнять операции удаления и переименования.
  • FILE_SHARE_READ Включает последующие операции открытия на
    файл или устройство для запроса доступа для чтения. В противном случае другие процессы не могут открыть файл или устройство, если они запрашивают доступ для чтения. Если этот флаг не указан, но файл или устройство были открыты для доступа для чтения, функция завершается ошибкой.
  • FILE_SHARE_WRITE Позволяет запрашивать последующие операции открытия файла или устройства
    доступ для записи.
    В противном случае другие процессы не смогут открыть файл или устройство, если они
    запрос на запись доступа.
    Если этот флаг не указан, но файл или устройство были открыты
    для доступа к записи или имеет отображение файла с доступом для записи, функция
    выходит из строя.
0

Хотя приведенные предложения хороши, такие как использование FILE_SHARE_READ, FILE_DELETE_ON_CLOSE и т. Д., Я не думаю, что есть абсолютно безопасный способ сделать это.

Я использовал Process Explorer, чтобы закрыть файлы, предназначенные для предотвращения запуска второго процесса — я сделал это, потому что первый процесс застрял и был «не убит и не мертв, но не отвечает», поэтому у меня была веская причина для этого — и я не хотел перезагружать машину в этот конкретный момент из-за других процессов, запущенных в системе.

Если кто-то использует какой-либо отладчик [включая что-то некоммерческое, написанное специально для этой цели], присоединяет к вашему запущенному процессу, устанавливает точку останова и останавливает код, затем закрывает открытый файл, он может записать в файл Вы только что создали.

Вы можете сделать это сложнее, но вы не можете помешать кому-то с достаточными привилегиями / навыками / возможностями перехватывать вашу программу и манипулировать данными.

Обратите внимание, что защита файлов / папок работает только в том случае, если вы точно знаете, что у пользователей нет привилегированных учетных записей на компьютере — обычные пользователи Windows либо являются администраторами сразу, либо имеют другую учетную запись для целей администратора — и у меня есть доступ к sudo / root на почти все блоки Linux, которые я использую на работе — есть некоторые файловые серверы, которые я не имею и не должен иметь root-доступ. Но все коробки, которые я использую сам или могу позаимствовать в целях тестирования, я могу получить в корневой среде. Это не очень необычно.

Решение, которое я могу придумать, состоит в том, чтобы найти другую библиотеку, которая использует другой интерфейс [или получить исходные коды библиотеки и изменить ее так, чтобы она]. Не то, чтобы это предотвращало атаку «останови, измени и иди», используя подход отладчика, описанный выше.

0

Создайте свой файл в папке вашего исполняемого файла с помощью API CreateFile. Вы можете присвоить имени файла некоторый UUID при каждом его создании, чтобы никакой другой процесс не мог угадать имя файла, чтобы открыть его. и установите его атрибут скрытым. После использования просто удалите файл. Достаточно ли этого?

-1
По вопросам рекламы [email protected]