現在、以下を使用するbashスクリプトを作成しています。inotifywait
ユーザーが提供したファイルとディレクトリのリストに対して特定のタスクを実行します。
それが私の関心を集めました。多くのシェルツールとは異なり、inotifywait
使用できません\0
。注入攻撃の可能性特別に設計された法的ファイル名(改行を含む)があります。
私のスクリプトが不要な脆弱性を引き起こさないように、この問題を解決したいと思います。私がする方法は次のとおりです。
inotifywait
ウォッチに渡されたすべてのファイル/パスの末尾のバックスラッシュが削除されていることを確認してください。- 次のように出力を生成するように
inotifywait
出力形式を指定します。--format "%e %w%f//"
<EVENT LIST> <FILE PATH>//
- 行末で見つかった
inotifywait
すべての項目を sed にパイプ出力します。//
\0
- Bash
while read
ループを使用して\0
区切られたレコードを読み取る - これは、最初のレコード以降のすべての後続レコードに追加の先行改行文字があることを意味します。これは剥がれています。
- その後、各レコードは最初のスペースで分割できます。スペースがイベントリスト(inotifywaitによってコンマで区切られている)になる前、スペースがイベントに関連付けられているフルパス名の後
#!/bin/bash
shopt -s extglob
watchlist=("${@}")
# Remove trailing slashes from any watchlist elements
watchlist=("${watchlist[@]%%+(/)}")
# Reduce multiple consecutive slashes to singles as per @meuh
watchlist=("${watchlist[@]//+(\/)/\/}")
printf -vnewline "\n"
inotifywait -qrm "${watchlist[@]}" --format "%e %w%f//" | \
sed -u 's%//$%\x00%' | \
while IFS= read -r -d '' line; do
line="${line#${newline}}"
events="${line%% *}"
filepath="${line#* }"
printf "events=%s\nfilepath=%q\n" "$events" "$filepath"
done
私が知っている限り、これはスペース、改行、引用符などの興味深い文字を含むファイル/パス名を処理します。しかし、これはやや村のパッチワークのようです。
この質問の目的に応じて、配列${watchlist[]}
はコマンドライン引数からコピーされましたが、配列はさまざまな方法で構成することができ、「興味深い」文字を含めることができます。
これを破るための悪意のある道はありますか?特定のイベントについて
$events
、および変数の内容が正しくない場合でも同じですか?$filepath
これが防水であれば、よりきれいな方法はありますか?
私は簡単に書くことができることを知っています。氏inotify_add_watch()
この問題を解決するには、Friendプログラムを呼び出します。しかし、今は他の依存関係のためにbashで作業しています。
私はこれをここに投稿するのか、codereview.SEにもメインso.SEに投稿するのかについて紛争を経験しました。
答え1
持つクロスNULで区切られた出力はサポートされており、次のように使用できます。
#!/bin/bash
shopt -s extglob
watchlist=("${@}")
# Remove trailing slashes from any watchlist elements
watchlist=("${watchlist[@]%%+(/)}")
printf -vnewline "\n"
inotifywait -qrm "${watchlist[@]}" --format "%e %w%f%0" | \
while IFS= read -r -d '' line; do
events="${line%% *}"
filepath="${line#* }"
printf "events=%s\nfilepath=%q\n" "$events" "$filepath"
done
--formatが使用されている場合、このバージョンはデフォルトで改行を追加しません。
答え2
にwatchlist
交換するにはクリーンアップが必要です。次の名前のディレクトリを検討してください(ここでは改行文字はどこにあります)。//
/
\nabc
\n
$ mkdir t
$ mkdir t/$'\nabc'
$ touch t/$'\nabc'/x
ディレクトリを見ると、行のt//$'\nabc'
末尾に偽の出力が表示されます。//
$ inotifywait -m -r t//$'\nabc' --format "%e %w%f//"
Setting up watches. Beware: since -r was given, this may take a while!
Watches established.
OPEN t//
abc/x//
ATTRIB t//
abc/x//
CLOSE_WRITE,CLOSE t//
abc/x//
入手する-c
代わりに参考にしてください。--format
データセットスタイル出力はファイル名を改行で二重引用符で囲みましたが、解析するのはより困難です。私の場合は、上記の例のコアダンプです。
-c
合計出力例touch t/$'new\nfile'
:
t/,CREATE,"new
file"