◉CLAUDE LABEN
●2.1.309 — サンドボックスと権限チェックが厳しくなり、Windows の hooks と PowerShell の不具合も直りました(10/22)●2.1.307 — スリープやキーチェーンロックのあとに MCP が再接続されない問題を修正しました(10/21)。2.1.306 では claude -p の誤表示も解消●SONNET 4.5 — Claude API での提供終了は 11/30、残り37日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.309 — サンドボックスと権限チェックが厳しくなり、Windows の hooks と PowerShell の不具合も直りました(10/22)●2.1.307 — スリープやキーチェーンロックのあとに MCP が再接続されない問題を修正しました(10/21)。2.1.306 では claude -p の誤表示も解消●SONNET 4.5 — Claude API での提供終了は 11/30、残り37日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/Claude Code
⟐ Claude Code/2026-10-24上級

「今後は確認しない」を押し続けた設定ファイルに、python3 が丸ごと通る一行がありました — 2.1.309 の更新履歴を読んで始めた許可ルールの棚卸し

2.1.309 は権限チェックとサンドボックスの修正が並ぶ版です。自分の settings.local.json の許可ルールを棚卸しするスクリプトと、インタプリタへの接頭辞ワイルドカードを見つけたときの直し方をまとめます。

Claude Code275パーミッション4settings.local.jsonサンドボックス9運用25

✦ プレミアム記事

土曜の夜、Claude Code の更新履歴で 2.1.309 の項目を読んでいて、手が止まりました。

権限チェックの修正が、びっくりするほど並んでいたのです。cd を挟んだ git の複合コマンド、Edit(path) の deny ルールとリダイレクト、変数を信用してしまう判定。どれも「ルールを書いた人の想定と、実際に通るものがずれる」種類の修正でした。

ふと、自分のルールはどうなっているのだろうと思いました。サイトの作業フォルダにある .claude/settings.local.json は、定期実行のたびに「今後は確認しない」を選んできたファイルです。最後に中身をきちんと読んだのがいつか、思い出せませんでした。

開いてみると、わずか 429 バイトでした

ファイルは小さく、permissions.allow に 6 件だけ入っていました。目で読めば済む量です。ただ、読んだだけでは「どこが問題か」を人に説明できないので、先に分類するスクリプトを書きました。

許可ルールは、1件ずつ「何が通るか」で数えて初めて見えてきます。

棚卸しスクリプト

公式の説明では、Bash ルールは最初の * より前の文字列が「書いたとおり」に照合されます。Bash(git log *) は git log だけ、Bash(git *) は git の全コマンドです。この性質を使って、危険度を5段階に分けています。

#!/usr/bin/env python3
"""settings(.local).json の permissions.allow を棚卸しして、危険度の高い順に並べる。"""
import json, re, sys
 
READONLY = {"ls", "cat", "echo", "pwd", "head", "tail", "grep", "wc", "which", "diff", "stat", "du"}
INTERPRETERS = {"python", "python3", "node", "bash", "sh", "zsh", "ruby", "perl",
                "deno", "bun", "npx", "uvx", "pwsh", "powershell"}
 
def classify(rule: str):
    m = re.fullmatch(r"(\w+)\((.*)\)", rule, re.S)
    if not m:
        return ("tool-wide", "括弧なし: そのツールを丸ごと許可")
    tool, body = m.groups()
    if tool != "Bash":
        return ("other", f"{tool} ルール(本スクリプトの対象外)")
    if "*" not in body:
        return ("exact", "完全一致: 想定どおり")
    head = body.split("*", 1)[0]          # 最初の * より前は「書いたとおり」に照合される
    words = head.split()
    prog = words[0] if words else ""
    if body.strip() == "*":
        return ("critical", "Bash(*) と同じ: 全コマンドを許可")
    if prog == "":
        return ("critical", "先頭が *: プログラム名で絞れていない")
    if prog.rsplit("/", 1)[-1] in INTERPRETERS:
        return ("critical", f"インタプリタ {prog} の接頭辞ワイルドカード: * 以降に任意のコードを書ける")
    if len(words) < 2 and not head.endswith(" "):
        return ("warn", f"{prog}* のように語の途中でワイルドカード")
    if len(words) < 2:
        if prog in READONLY:
            return ("ok", f"{prog} は読み取り専用の組み込み集合")
        return ("warn", f"{prog} の全サブコマンドを許可(サブコマンドの後ろに * を置く)")
    return ("ok", "プログラム + サブコマンドで絞れている")
 
ORDER = {"critical": 0, "warn": 1, "tool-wide": 2, "other": 3, "exact": 4, "ok": 5}
 
def main(path):
    allow = json.load(open(path)).get("permissions", {}).get("allow", [])
    rows = sorted(((classify(r), r) for r in allow), key=lambda x: ORDER[x[0][0]])
    for (level, why), rule in rows:
        print(f"{level:9} {rule[:70]!r:74} {why}")
    bad = sum(1 for (lv, _), _r in rows if lv in ("critical", "warn", "tool-wide"))
    print(f"-- {len(allow)} 件中 {bad} 件が要見直し")
    return 1 if bad else 0
 
if __name__ == "__main__":
    sys.exit(main(sys.argv[1]))

書き方に2つ理由があります。ひとつは、終了コードを 0 / 1 にして、定期実行の前段に置けるようにしたこと。もうひとつは、READONLY を例外にしたことです。最初の版では Bash(ls *) まで警告が出てしまい、読むほうが疲れました。公式が読み取り専用として扱うコマンドは、そもそも許可なしで通ります。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦自分の settings.local.json を開いて、許可ルールのうち「任意のコードが通る一行」を数秒で見つけ出せるようになる
✦python3 や node への接頭辞ワイルドカードを、固定スクリプト+書き換え禁止の組み合わせに置き換えて、便利さを残したまま穴だけ塞げるようになる
✦新しい版が出るたびに全文を読まなくても、更新履歴から「自分の許可リストを見直す日かどうか」を5分で判断できるようになる
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

⟐ Claude Code2026-10-23
夜間の claude -p で MCP が「認証待ち」になった朝、sleep と keychain を切り分ける事前確認を足しました
Claude Code 2.1.307 は macOS の sleep とログインキーチェーンのロックが原因の MCP 失敗を修正しました。修正の有無に関わらず効く事前確認スクリプトと、sleep 履歴との照合手順をまとめます。
⟐ Claude Code2026-10-18
allow を足したのに承認画面が消えない — /permissions で「どの層が決めたか」を6段で読む
settings に allow を書いたのに、同じ承認画面が出続けるときの切り分けです。ask・deny の先勝ち、settings.local.json の置き場所、Cowork の Bash など、公式の権限ドキュメントで確認できる6つの層を、/permissions の表示から順に読みます。
⟐ Claude Code2026-09-22
消えたことになっている作業ツリーの棚卸しと、隔離の任せどころ
サブエージェントに任せた隔離作業ツリーが畳まれずに残っていました。git 2.34.1 で実測した remove の可否、消しても残るブランチ、1 ツリーあたり 12 MB の差から、棚卸しの手順と隔離の任せどころをお伝えします。