Як я можу безпечно створити та отримати доступ до тимчасових файлів із скриптів оболонки?


14

Я читав, що перенаправлення виводу у файл з фіксованим іменем /tmpможе бути ризиком для безпеки, тому що якщо зловмисник (або невмілий вміст) помітить, що файл /tmp/tmpfileformyscript.tmpстворюється під час запуску сценарію (навіть якщо він не має доступу до читання до мого скрипт), він, наприклад, може зробити симпосилання, ln -s ~wildcard/.bashrc /tmp/tmpfileformyscript.tmpяке змусить мене знищити .bashrcфайл під час запуску сценарію.

Тож замість цього я можу використовувати щось подібне filename="tmpfile.tmp.$RANDOM" ; echo outputtext > "$filename".

Однак я хотів би іноді використовувати файл tmp для кешування, і в такому випадку я хотів би знати, чи відповідає "tmpfile.tmp. *" Чомусь, /tmpі якщо так, використовувати цей файл, а не створювати новий. На жаль, testі подібний [ -f filename ]файл не підтримує глобалізацію файлів, наскільки я можу сказати.

Таким чином, моє питання двояке:

  1. Як я можу безпечно створити тимплейф? Чи "predictablename.$RANDOM"прийнятна практика чи існує кращий (більш безпечний, простіший) спосіб?
  2. Як я можу легко отримати доступ до файлу та / або встановити його існування пізніше, перевіривши predictablename?

Відповіді:


13

Використовуйте mktempутиліту для створення тимчасового файлу з непередбачуваним іменем. Він не стандартизований POSIX, але він доступний як у * BSD, так і в Linux.

> /tmp/predictable.$RANDOMце не гарний вибір, тому що він здебільшого передбачуваний¹, який відкриває ваш скрипт атаці, коли зловмисник може обманути ваш сценарій перезаписати файл, до якого ви маєте доступ до запису, або надаючи їм доступ до тимчасового файлу. Це незахищена тимчасова вразливість файлів . mktempне має цієї вразливості, оскільки створює файл безпечно (він не перезапише існуючий файл, навіть якщо символічні посилання задіяні) та використовує достатньо непередбачуване ім'я, щоб уникнути відмови в наданні послуги.

Якщо створити один тимчасовий файл та працювати з ним недостатньо добре, створіть тимчасовий каталог із ним mktemp -dі працюйте там.

mktempтакож дбає про використання, $TMPDIRякщо змінна встановлена, повертаючись до, /tmpякщо вона не встановлена.

Все більше і більше дистрибутивів, створених TMPDIRдля приватного каталогу, наприклад, /run/1234/tmpде 1234ваш UID. Це виключає ризик тимчасової вразливості файлів, ціною більше неможливості ділитися тимчасовими файлами між користувачами (що інколи корисно, але не дуже часто; /tmpвсе ще доступно, просто не TMPDIR).

Якщо вам потрібно відтворити ім'я файлу, тоді створіть файл із чітко визначеним іменем (без випадкових компонентів) у домашньому каталозі користувача. Сучасна конвенція - специфікація каталогу XDG . Якщо файл можна було видалити, не спричиняючи втрати даних, використовуйте XDG_CACHE_HOMEзмінну оточення, дефолт - до ~/.cache. Ймовірно, ви повинні створити підкаталог, названий за вашою заявкою, і працювати там.

CACHE_DIR="${XDG_CACHE_HOME:-"$HOME/.cache"}"/Wildcard-scripts
[ -d "$CACHE_DIR" ] || mkdir -p -- "$CACHE_DIR"
CACHE_FILE="$CACHE_DIR/tmpfileformyscript"

¹ Має не $RANDOMлише 32767 можливих значень, але легко передбачити, навіть не намагаючись багато значень. Генератор випадкових чисел Баша - це LCG, посіяний PID та часом першого використання. Zsh's - це платформа, randзасіяна часом запуску. ATT Ksh's - платформа, randзасіяна PID. Mksh's - це LCG з більш складним, але все ще не безпечним насінням. Всі вони можуть бути спрогнозовані іншим процесом з досить великими шансами на успіх.


Власне, ваше обговорення $TMPDIRі ~/.cacheсаме те, що мені було потрібно. Після деякої подальшої думки я зрозумів, що єдина причина, за якою я цього хотіла, - це /tmpрозділення - тому кеш не міг заповнити /homeрозділ. Але для цього випадку використання є справді повною проблемою, тому підкаталог повністю ~/.cacheвідповідає моїм потребам і уникає проблеми безпеки.
Wildcard

mktempнедоступний на AIX або оболонці Git в Windows. Схоже, file.$RANDOM$RANDOMце портативне рішення. $RANDOM$RANDOMМає збільшити простір до 2 ^ 32, припускаючи Баш випадкових результати є незалежними і не слабкими.

@jww Баш випадкові результати слабкі: це LCG, який приблизно настільки передбачуваний, як він отримує, при цьому досить хороший для багатьох програм, які не потребують непередбачуваності.
Жил "ТАК - перестань бути злим"

9

mktemp був розроблений для цього. На чоловіковій сторінці:

TMPFILE=`mktemp /tmp/example.XXXXXXXXXX` || exit 1
echo "program output" >> $TMPFILE

mktemp створить файл або вихід із ненульовим статусом виходу. Логічний або (||) гарантує, що сценарій вийде, якщо mktemp не в змозі створити файл. Після цієї команди ви можете бути впевнені, що файл доступний. Не потрібно перевіряти це ще раз. Єдине, що вам може знадобитися додати - це очищення файлу в кінці сценарію.

І, можливо, також, коли сценарій припиняється сигналом. Вам потрібно вирішити, чи потрібно це чи ні.

І те й інше можна зробити за допомогою trapкоманди.


Ах! Це дуже корисно; тоді мені не потрібно дзвонити $RANDOM. Але потім частина 2 мого питання - як я можу отримати доступ до цього файлу пізніше або перевірити, чи він уже існує при наступному запуску сценарію? (Для реалізації дуже простого кешу.)
Wildcard
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.