はじめに
どうも、水無月せきなです。
遅まきながらClaude Codeを使い始めて、ふと気になりました。
「.envとかリポジトリにあるけど、読まれるのかな?」
気になったからには、ちょっと調べてみましょう。
先に結論
デフォルトだと機密ファイル(.envなど)を読み取れるので、.claude/settings.json を作成して機密ファイルの読み書きをdenyに指定しましょう
読み取りを阻止する設定
とりあえず、.envや.env.localといったファイルの読み取りを阻止する場合は下記のようになります。
{
"permissions": {
"allow": [
],
"deny": [
"Read(.env*)"
]
}
}
調査
試しに、下記のファイルを作ってみます。
SAMPLE="test!"
Claude Codeに上記のファイルの内容を教えてもらいます。
> .env.localの内容を教えて
● Read(.env.local)
⎿ Read 1 line (ctrl+r to expand)
● .env.localにはSAMPLE="test!"が含まれています。
ファイルの内容を読み取れました。
今度は、下記のファイルを用意しましょう。
ENVIRONMENT=DEV
> .env.の内容を教えて
● Read(.env)
⎿ Read 1 line (ctrl+r to expand)
● .envにはENVIRONMENT=DEVが含まれています。
ファイルの内容が返ってきました。
今度は、.claude/settings.jsonを作成します。
{
"permissions": {
"allow": [
],
"deny": [
"Read(.env*)"
]
}
}
作成後、一度Claude Codeのセッションを開き直します。
# ここはClaude Codeの中で実行
/exit
# もう一度開く
claude
そして、さっきと同じように聞いてみましょう。
> .env.localの内容を教えて
● Read(.env.local)
⎿ Error: Permission to read /workspaces/LangChain-ChatApp/.env.local has been denied.
● .env.localファイルを読み取る権限がありません。ファイルの権限やアクセス設定を確認してください。
読み取りに失敗しました。
> .env.の内容を教えて
● Read(.env)
⎿ Error: Permission to read /workspaces/LangChain-ChatApp/.env has been denied.
● .envファイルを読み取る権限がありません。セキュリティ上、環境変数ファイルへのアクセスが制限されています。
こちらも失敗しました。
結果
| 条件 | 結果 |
|---|---|
| denyなし | 読み取れる |
| "deny": ["Read(.env*)"] | 読み取れない |
追加調査(2025/07/17)
.claude/settings.jsonに"deny": ["Read(.env*)"]を設定していたものの、.env系のファイルを読まれる事象が発生しました。
ダメもとでClaude Codeに聞いたところ、以下の回答を得ました。
確かに13行目で"Read(.env*)"がdenyリストに含まれています。しかし、私が.env.localを読めた理由は、この設定がワークスペースのルートレベル(/workspace/.claude/settings.json)にあるのに対し、実際に読んだファイルは/workspace/hoge/.env.localというサブディレクトリ内にあるためです。
設定の権限制御はワークスペースのルートからの相対パスで動作するようで、サブディレクトリ内の.env*ファイルは制限対象外になっているようです。
実際、ワークスペースのルートレベルに移動すると、読めなくなりました。
それから色々試した(Read(**/.env*)など)のですが、ディレクトリを移動すると読めてしまう事象は変わらず……
一旦、Claudeを起動するディレクトリに気を付けてやろうと思います……
補足
Cursorは?
Cursorは.cursorignoreをルートディレクトリに作ることで制御できます。
ただ、**/.envといった機密ファイルは読み取れないようにグローバルで設定されています。
この点は安心ですね。
まとめ
ということで、Claude Codeはデフォルトの状態だと.envといった機密ファイルを読み取れるので、セキュリティを気にする場合は.claude/settings.jsonでdenyを指定した方が良いでしょう。
既に包括的なdenyルールを公開されている方がいらっしゃったので、その方の記事と、ほんの少しだけ修正したルールを掲載して終わりにしたいと思います。
ここまでお読みいただき、ありがとうございました。
.claude/settings.json
元記事だと"Read(.env.*)"となっている箇所を"Read(.env*)"に変えました。
.envの読み取りを止められなかったからです。
{
"permissions": {
"allow": [
],
"deny": [
"Bash(sudo:*)",
"Bash(rm:*)",
"Bash(rm -rf:*)",
"Bash(git push:*)",
"Bash(git commit:*)",
"Bash(git reset:*)",
"Bash(git rebase:*)",
"Read(.env*)",
"Read(id_rsa)",
"Read(id_ed25519)",
"Read(**/*token*)",
"Read(**/*key*)",
"Write(.env*)",
"Write(**/secrets/**)",
"Bash(curl:*)",
"Bash(wget:*)",
"Bash(nc:*)",
"Bash(npm uninstall:*)",
"Bash(npm remove:*)",
"Bash(psql:*)",
"Bash(mysql:*)",
"Bash(mongod:*)",
"mcp__supabase__execute_sql"
]
},
}


