2012-06-11 11 views
111

bashスクリプトで一時ファイルを作成する客観的に優れた方法はありますか?bashで一時ファイルを作成する

通常は、スクリプトが終了したら削除されるので、tempfile-123のようなものは私の頭に浮かぶものです。現在のフォルダ内の一時ファイル-123を上書きする以外の方法で不利な点はありますか?または、より注意深い方法で一時ファイルを作成することに利点がありますか?

+0

一時ファイルを使用しないでください。代わりに一時的なディレクトリを使用してください。そして、mktempを使わないでください。ここを参照してください理由:http://www.codeproject.com/Articles/15956/Security-Tips-for-Temporary-File-Usage-in-Applicat – ceving

+14

@ceving少なくともシェルコマンドに適用すると、その記事は単に間違っていますmktemp(mktempライブラリ呼び出しとは対照的に) mktempは制限されたumaskでファイル自体を作成するので、与えられた攻撃は攻撃者が攻撃者と同じアカウントで操作している場合にのみ機能します。この場合、ゲームは既に失われています。シェルスクリプトの世界でのベストプラクティスについては、http://mywiki.wooledge.org/BashFAQ/062を参照してください。 –

+0

それを持っているシステムでは、 'tempfile(1)'を使うこともできます。 –

答えて

135

mktemp(1) manページはかなりよくそれを説明する:

伝統的に、多くのシェルスクリプトは、サフィックスと使用として でPIDをプログラムの名前を取りますそれは一時的なファイル名です。この種の の命名規則は予測可能であり、作成する競合条件は攻撃者が勝つのが容易な です。まだ安全ではありますが、やはり というアプローチは、同じ命名体系を使用して一時ディレクトリを作成することです。 これにより、一時ファイルが無効になることを保証することができますが、それでも単純なDoS攻撃が可能です。 については、これらの理由から、代わりにmktempを使用することをお勧めします。スクリプトで

、私は私が働くことができ、そしてその中で、私は安全に実際のファイルに読みやすく、有益な何かに名前を付けることができ、一時ディレクトリを作成します

mydir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX") 

ようmktempの何かを呼び出します。

mktempは標準ではありませんが、多くのプラットフォームに存在します。 "X"は一般的にランダムに変換され、よりランダムになるでしょう。しかし、いくつかのシステム(1用busyboxの灰は、)ところでより大幅に他人


よりも、このランダム性を制限し、一時ファイルを安全に作成するには、単にシェルスクリプトよりものために重要です。Pythonはtempfileを持っている理由です、perlは

+1

-tオプションは推奨されていません:http://www.gnu.org/software/coreutils/manual/html_node/mktemp-invocation.html –

+1

@TeaBeeはOS Xにはありません。 – kojiro

+6

最も安全で最もクロスプラットフォームのようです'mktemp'を使う方法は、' mktemp -dt "$(basename $ 0).XXXXXXXXXX" 'のように、' basename'と組み合わせています。 'basename'を付けずに使用すると、_mktempのようなエラーが出る可能性があります:無効なテンプレート' /tmp/MOB-SAN-JOB1-183-ScriptBuildTask-7300464891856663368.sh.XXXXXXXXXX 'にはディレクトリseparator_が含まれています。 – i4niac

15

あなたはmktemp

で見たいと思うかもしれませんmktempをユーティリティは、指定したファイル名のテンプレートを取り、一意のファイル名を作成することの 部分を上書きします。テンプレートには、 のファイル名に「Xs」が追加されたファイルがあります。たとえば、 /tmp/tfile.XXXXXXXXXXです。末尾の 'Xs'は、現在のプロセス番号とランダムな文字の組み合わせに置き換えられます。詳細については

man mktemp

26

はい、mktempを使用しています。

一時ファイルを保存するために設計されたフォルダ内に一時ファイルが作成され、一意の名前が保証されます。これは、そのファイルの名前を出力します

> mktemp 
/tmp/tmp.xx4mM3ePQY 
> 
9

...ルビーはTempfile、などがあり、File::Tempを持っている中で、一時ファイルは通常、作成され、より慎重な方法で

を一時ファイルを作成する際にどんな利点があります(/tmpなど)他のすべてのユーザーとプロセスに読み取りと書き込みのアクセス権があります(他のスクリプトはそこに新しいファイルを作成できます)。したがってスクリプトは、適切な権限(例えば、所有者のためだけに読んでください:help umaskを参照)を使用してファイルを作成するように注意する必要があり、ファイル名は簡単には推測できません(理想的にはランダムです)。そうでない場合、ファイル名が一意でない場合、同じスクリプトが複数回実行された場合(たとえばrace condition)、攻撃者が機密情報をハイジャックする(たとえば、アクセス権があまりにも開いていてfilenameが推測しやすい場合)ファイルを独自のバージョンのコードに置き換えます(格納されている内容に応じてコマンドやSQLクエリを置き換えるなど)。


あなたは一時ディレクトリを作成するには、次のアプローチを使用することができます。

TMPDIR=".${0##*/}-$$" && mkdir -v "$TMPDIR" 

や一時ファイル:

TMPFILE=".${0##*/}-$$" && touch "$TMPFILE" 

は、しかし、それはまだ安全と考えられる予測可能ではありません。

man mktempあたりのように、私たちは読むことができます:

は伝統的に、多くのシェルスクリプトは、一時ファイル名としてサフィックスとしてPIDを持つプログラムの名前を取り、使用しています。この種の命名体系は予測可能であり、作成する競合状態は攻撃者が勝つのが容易です。

したがって、一意の一時ファイルまたはディレクトリ(-d)を作成するには、mktempコマンドを使用することをお勧めします。

+2

質問された内容と正確に一致しません。しかし、それは完璧な解決策になる可能性があります。 – jpbochi

+1

@jpbochi私はこの問題に対処するための答えを改善しました。それが役に立ったら教えてください。 – kenorb

+0

それは確かに答えを改善します。私のアップヴォートはすでにあなたのものでした。もっと投票できません。私が持っている提案の1つは、 '$ {0 ## * /}'と '$$'が何に展開されているのか、それに関するいくつかの文書にリンクすることです。 – jpbochi

関連する問題