引数にパスワードを取るようなコマンドで困ること
ps コマンドの出力や /proc/<pid>/cmdline でパスワードがそのまま見えてしまう。
curl のようにパスワードを隠してくれるものはいいが、そうでないものを使うときに困る。(curl も長さは分かるけど)
回避策
※ ARG_MAX が PAGE_SIZE より充分大きい環境が前提。
引数を無関係な文字列で埋める。
どれくらい長さがいるかは、PAGE_SIZE を調べれば良さそう。
でも ps コマンドを叩くと出力が鬱陶しいことになるので、なるべく使わない。
$# 通常の実行
$ wget -q --user=foo --password=bar http://example.com/ &
$ ps auxww | grep wge[t]
hoge 23277 0.0 0.1 134300 2212 pts/0 S 00:17 0:00 wget -q --user=foo --password=bar http://example.com/
$# パディングして実行
$ s=$(getconf PAGE_SIZE)
$ pad=$(perl -e "print 'x' x $s")
$ wget -q --user=$pad --user=foo --password=bar http://example.com/ &
$ ps auxww | grep wge[t]
hoge 23281 0.0 0.1 134304 2212 pts/0 S 00:18 0:00 wget -q --user=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(以下略)
上記の例 (wget) だと後から指定した --user=foo の方だけが有効になる
引数の処理方法は実装に依存するので、コマンドによって適切な方法を使う。
java なら java -cp $pad -cp <true_class_path> class のようにする
参考: curl の引数隠ぺい
src/tool_getparam.c
case 'u':
/* user:password */
GetStr(&config->userpwd, nextarg);
cleanarg(nextarg);
break;
src/tool_paramhlp.c
void cleanarg(char *str)
{
#ifdef HAVE_WRITABLE_ARGV
/* now that GetStr has copied the contents of nextarg, wipe the next
* argument out so that the username:password isn't displayed in the
* system process list */
if(str) {
size_t len = strlen(str);
memset(str, ' ', len);
}
#else
(void)str;
#endif
}