0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

bash -x でデバッグすると .env の値も API キーも展開されて出力に出る:set +x と curl -H @file の効く範囲を実機で確認

0
Posted at

結論

  • シェルスクリプトを bash -x(または set -x)で動かすと、変数を展開したあとのコマンドが標準エラーに出ます。source .env した値も、curl -H "Authorization: Bearer $API_KEY" のキーも、そのまま表示されました(2026-11-05、bash 5.2.37・ダミー値で実機確認)。
  • curl -H @headers.txt のようにヘッダーをファイルから読ませると、bash -x の表示はファイル名だけになりました。ただし curl -v を付けると、ファイルから読んだヘッダーも > Authorization: Bearer ... と表示されました(curl 8.14.1)。
  • AIエージェントにスクリプトのデバッグを頼むと、bash -x の出力がそのまま会話に入ることがあります(推測。今回はエージェント経由では試していません)。スクリプトに set -x が残っていないかは、下の1行で確かめられます。

この記事は「AIエージェントと秘密情報」の検証シリーズです。新しい検証は X(@supportapp3_lab)でもお知らせしています。

試してみる(set -x が残っているスクリプトを探す)

プロジェクトのフォルダで実行すると、set -x・set -o xtrace・bash -x を書いた行のファイル名と行番号を出します。

grep -rnE --include='*.sh' 'set -x|set -o xtrace|bash -x' .

出てきたスクリプトで .env を読んだり、キーをコマンドに渡したりしていれば、実行ログに値が出ます。

公式の説明

bash 組み込みの help set(bash 5.2.37)には次のように書かれています。

-x Print commands and their arguments as they are executed.
Using + rather than - causes these flags to be turned off.

curl の公式マニュアルの -H, --header には、@filename 形式で渡すと「adds a header for each line in the input file」と書かれています。

実機で確かめたこと

値はすべてダミーです。.env は API_KEY=sk-dummy-0000-not-real の1行、送り先は手元の python3 -m http.server(127.0.0.1)です。

1. source .env と curl のヘッダー

set -a; source ./.env; set +a
curl -s -o /dev/null -H "Authorization: Bearer $API_KEY" http://127.0.0.1:18765/

bash -x a.sh の出力です。

+ set -a
+ source ./.env
++ API_KEY=sk-dummy-0000-not-real
+ set +a
+ curl -s -o /dev/null -H 'Authorization: Bearer sk-dummy-0000-not-real' http://127.0.0.1:18765/

.env の中の代入行も、展開後の curl の引数も、両方にキーが出ました。

2. $(cat .env) で読んだ場合

API_KEY=$(cat ./.env | cut -d= -f2)
export API_KEY
++ cut -d= -f2
++ cat ./.env
+ API_KEY=sk-dummy-0000-not-real
+ export API_KEY

コマンド置換の結果も、代入の行で値が出ました。

3. ヘッダーをファイルから読ませる

headers.txt に Authorization: Bearer sk-dummy-0000-not-real を書き、chmod 600 にしました。

curl -s -o /dev/null -H @headers.txt http://127.0.0.1:18765/
+ curl -s -o /dev/null -H @headers.txt http://127.0.0.1:18765/

bash -x に出るのはファイル名だけでした。

4. ただし curl -v には出る

$ curl -sv -o /dev/null -H @headers.txt http://127.0.0.1:18765/ 2>&1 | grep -i authorization
> Authorization: Bearer sk-dummy-0000-not-real

-H に直接書いた場合も、ファイルから読ませた場合も、-v の表示には送ったヘッダーがそのまま出ました(curl 8.14.1)。

5. 一部だけ止める(set +x)

set -a; source ./.env; set +a
{ set +x; } 2>/dev/null
curl -s -o /dev/null -H "Authorization: Bearer $API_KEY" http://127.0.0.1:18765/
set -x
echo done
+ set -a
+ source ./.env
++ API_KEY=sk-dummy-0000-not-real
+ set +a
+ echo done

{ set +x; } 2>/dev/null のあとの curl は出なくなりました。ただし止める前の source ./.env は出ています。止めるなら .env を読む前に止める必要があります。

AIエージェントとの関係(ここからは推測を含みます)

  • AIエージェントは、コマンドの標準出力と標準エラーを読んで次の手を考えます。bash -x で動かせば、上の出力がそのまま会話に入り、ログやクラウド側の会話記録にも残ると考えられます(推測)。会話記録の保存先は Claude Code の会話記録の記事で確かめています。
  • 「動かないので bash -x で見て」と頼むのはよくある使い方なので、.env を読むスクリプトでは特に注意が要ると考えられます(推測)。

対策

  1. 上の1行で、set -x が残っていないか確かめる。
  2. デバッグで set -x を使うときは、.env を読む前と、キーを渡すコマンドの前で { set +x; } 2>/dev/null で止める。
  3. curl のヘッダーは -H @ファイル で渡す(bash -x には出なくなる)。ただし -v は付けない。
  4. AIに bash -x の出力を貼るときは、キーが入っていないか先に見る。

ai-secret-check について

筆者が作った読み取り専用の CLI ai-secret-check scan は、AIが読めそうな場所にある .env 系のファイル名を探します(中身は表示しません)。今回のような「実行ログに出る」ケースは見られないので、上の grep で別に確かめてください。

npx github:supportapp3-lab/ai-secret-check scan

リポジトリ: https://github.com/supportapp3-lab/ai-secret-check (Node.js 20以上、MIT)

参考

※ 2026-11-05 に、Debian の使い捨てフォルダとダミー値で確かめました(bash 5.2.37、curl 8.14.1)。

更新情報やちょっとしたTipsは X(@supportapp3_lab)で発信しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?