シェルスクリプトから一時ファイルを安全に作成してアクセスするにはどうすればよいですか?


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 ]私が知る限り、同等のものはファイルグロビングをサポートしていません。

したがって、私の質問は2つあります。

  1. 一時ファイルを安全に作成するにはどうすればよいですか?"predictablename.$RANDOM"受け入れられるプラクティスですか、それともより良い(より安全で簡単な)方法がありますか?
  2. 確認することで、ファイルに簡単にアクセスしたり、後でその存在を確認したりするにはどうすればよいpredictablenameですか?

回答:


13

mktempユーティリティを使用して、予測できない名前の一時ファイルを作成します。POSIXでは標準化されていませんが、Linuxと同様に* BSDでも利用可能です。

> /tmp/predictable.$RANDOMほとんど予測可能であるため¹は適切な選択肢ではありません¹。攻撃に対してスクリプトを開き、攻撃者はスクリプトをだまして書き込みアクセス権のあるファイルを上書きしたり、一時ファイルへのアクセス権を与えたりすることができます。これは、安全でない一時ファイルの脆弱性です。mktempファイルを安全に作成し(シンボリックリンクが含まれていても既存のファイルを上書きしない)、サービス拒否を回避するために十分に予測できない名前を使用するため、この脆弱性はありません。

一時ファイルを1つ作成して作業するだけでは不十分な場合は、で一時ディレクトリを作成し、mktemp -dそこで作業します。

mktempまた$TMPDIR、変数が設定されている場合は使用に注意し、設定されてい/tmpない場合はフォールバックします。

ますます多くのディストリビューションTMPDIRがプライベートディレクトリに設定されています。たとえば、UIDは/run/1234/tmpどこに1234ありますか。これにより、一時ファイルの脆弱性のリスクが排除されますが、ユーザー間で一時ファイルを共有できなくなるという犠牲が生じます(これは有用な場合が/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"

¹ するだけでなく、$RANDOM32767の可能な値がかかりますが、それも多くの値をしようとせずに予測するのは簡単ですだけ。Bashの乱数ジェネレーターは、PIDと初回使用時にシードされたLCGです。Zshのプラットフォームは、rand起動時にシードされます。ATT Kshは、randPIDによってシードされたプラットフォームです。Mksh'sは、より複雑ですが、セキュリティ品質の種ではないLCGです。それらはすべて、成功の可能性がかなり高い別のプロセスで予測できます。


実際のあなたの議論$TMPDIRとは、~/.cache私がまさに必要です。さらに考えた後、私はそれが欲しかった唯一の理由/tmpがパーティショニングであることに気づいたので、キャッシュが/homeパーティションをいっぱいにすることができませんでした。しかし、このユースケースでは実際には完全な非問題であるため、サブディレクトリは~/.cache私のニーズに完全に適合し、セキュリティの問題を回避します。
ワイルドカード

mktempAIXまたはWindowsのGitシェルでは使用できません。file.$RANDOM$RANDOMポータブルなソリューションのようです。$RANDOM$RANDOMバッシュランダムな結果が弱く独立していないと仮定すると、2 ^ 32にスペースを増やす必要があります。

@jww Bashのランダムな結果は弱いです。それはLCGであり、予測不可能なことを必要としない多くのアプリケーションにとって十分でありながら、ほぼ予測可能です。
ジル 'SO-悪であるのをやめる'

9

mktempはこのために設計されました。manページから:

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

mktempは、ファイルを作成するか、ゼロ以外の終了ステータスで終了します。論理or(||)は、mktempがファイルを作成できない場合にスクリプトが終了することを保証します。このコマンドの後、ファイルが使用可能であることを確認できます。再度確認する必要はありません。追加する必要があるのは、スクリプトの最後にあるファイルのクリーンアップだけです。

また、場合によっては、スクリプトがシグナルによって終了した場合もあります。それが必要かどうかはあなたが決めなければならないものです。

どちらもtrapコマンドを使用して実行できます。


あ!これは非常に便利です。それから私は電話する必要はありません$RANDOM。しかし、私の質問のパート2-後でそのファイルにアクセスしたり、スクリプトの後続の実行で既に存在するかどうかを確認したりするにはどうすればよいですか?(非常に単純なキャッシュを実装するため。)
ワイルドカード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.