コードを書いたあと「これ脆弱性ないかな」と気になるけど、自分でセキュリティ知識を全部覚えてはいない人向け
コードを書き換えた直後、まだコミット(変更を「ここまで保存」と区切る操作)していないタイミングで、フォーム送信処理や認証まわりなど普段書き慣れない領域のセキュリティ点検をしたいときに叩く。コミットを全部済ませてリポジトリ(プロジェクト一式の保管箱)が「変更なし」状態になっていると、見るものがないので何も指摘が出ない
コードを書き終えたあと、「これ脆弱性入ってないかな」とふと不安になる瞬間がありますよね。/security-review はまさにその不安を、いま書き換えた範囲だけに絞ってClaudeに点検させるためのスラッシュコマンドです。SQLインジェクション、入力のチェック漏れ、シークレット(APIキーなど秘密の文字列)の貼り付け事故、認証・権限まわりのミス——よくあるセキュリティ上の地雷を、Claudeが書き換え部分のコードを読んで指摘してくれます。
「全部のセキュリティ知識を覚えてから書く」のではなく、「書いてから1回叩いて、危なそうなところを拾ってもらう」運用が前提です。
噛み砕くと
このコマンドは、文章を書き終えたあとに通す「校正担当」に近い動きをします。ただし校正の範囲は記事全体じゃなくて、いま書き直した箇所だけ。
もう少し具体的に言うと、Gitで「まだ保存し終わってない変更」と「保存はしたけどまだ確定していない変更」を読み取って、その差分(前のコードと今のコードの違い)だけをClaudeにセキュリティ目線で見せます。なので、ファイルを書き換えた直後・コミット直前に叩くのが一番効きます。
大事な前提:このコマンドは「変更があるとき」しか働かない
ここが最初に詰まりやすいポイントです。/security-review が見るのは「いま書き換え途中の差分」だけ。なので、すべての変更を保存して、コミットも済んで、リポジトリ(プロジェクトの保管庫)が「きれいな状態」になっていると、Claudeは「変更がないので何も見るものがない」と返してきます。
逆に言うと、コードを書き換えた直後、まだ「ここまで保存」の区切りを入れていないタイミングで叩くのが正解です。
「副業のお問い合わせフォーム」を例に、実際の手順を見る
副業で作っているお問い合わせフォームのバックエンド(送信を受け取るサーバー側のコード)を書き終えたところを想定します。題材はPHPで、contact_submit.php というファイルにフォームの送信処理を書いた直後です。
ステップ1: コードを書き終えてターミナルで状態を確認する
まず、いまの変更がGitから見てどう見えているかを確認します。
$ git status
On branch feature/contact-form
Changes not staged for commit:
modified: contact_submit.php
contact_submit.php が「書き換えたけど、まだ保存しきってない」状態で出ています。この状態で /security-review が一番効きます。
ステップ2: Claude Codeのセッション内で叩く
Claude Codeを起動した状態で、入力欄にこう打つだけです。
/security-review
後ろには何も書き足しません。コマンドだけそのまま叩く形です。Claudeが自動で git diff 相当を読み取って、変更分のコードに目を通し始めます。
ステップ3: Claudeが指摘を返してくる
たとえばPHPで以下みたいなコードを書いていたとします。
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$sql = "INSERT INTO contacts (name, email, message)
VALUES ('$name', '$email', '$message')";
mysqli_query($conn, $sql);
これに対してClaudeはだいたいこんな指摘を返してきます。
HIGH: SQLインジェクションの脆弱性
contact_submit.php:12で$_POSTの値を直接SQL文に埋め込んでいます。攻撃者がname欄に', ''); DROP TABLE contacts; --のような値を送ると、テーブルごと削除される可能性があります。プリペアドステートメント(mysqli_prepare+bind_param)に書き換えてください。MEDIUM: 入力検証の不足
filter_var($email, FILTER_VALIDATE_EMAIL)でバリデーション(入力値が想定通りかのチェック)を入れることを推奨します。LOW: HTMLエスケープ漏れ
管理画面で$messageをそのまま表示する場合、htmlspecialchars()を通さないとXSS(埋め込まれた悪意のあるスクリプトが他人のブラウザで動く現象)の可能性があります。
ステップ4: 指摘の優先度で対応を決める
HIGH(高)→ MEDIUM(中)→ LOW(低)の順で深刻度が下がります。HIGHは即修正、MEDIUMはこのPRで一緒に直す、LOWはあとで別タスクに、みたいに整理するとスムーズです。
ここで初心者がやりがちな勘違いがあります。Claudeの指摘は便利ですが、Claudeの判断ベースなので「漏れ」も「誤検出」もあり得ます。HIGHの指摘でも内容を読んで「これは違うな」と思ったら無視してOK、逆にClaudeが指摘してこない箇所でも気になるなら追加で確認すべきです。
ステップ5: 修正してもう一度叩く
SQLインジェクション部分をプリペアドステートメントに書き換えたあと、もう一度 /security-review を叩くと、新しい差分(修正分)に対してまたチェックが入ります。修正で別の脆弱性を入れてしまった場合にも気づけます。
ステップ6: 問題なくなったらコミットする
指摘がなくなった、または残った指摘について「この案件では許容する」と判断できたら、いつも通り git commit で保存します。コミット後はGitから見て「変更なし」状態に戻るので、その状態で /security-review を叩いても何も指摘は出ません。
つまり /security-review は何をしてくれるのか
- やってくれる: いま書き換え途中のコード(保存し終わってない変更+確定前の変更)を読んで、SQLインジェクション、XSS、認証・権限の抜け、シークレット混入、入力チェック漏れなど、よくあるセキュリティ上の地雷を箇条書きで指摘する
- やってくれない: リポジトリ全体のセキュリティ監査。過去のコミットに埋まっている脆弱性は対象外。「ファイルを開く前のコード」と「いま書き換え後のコード」の違いだけを見ます
- 意味が薄い場面: コミットを全部済ませてリポジトリが「きれい」な状態。変更が無いとClaudeに見せる材料が無いので、何も指摘が出ません
使いどころ3シナリオ(具体題材で再現)
シナリオ1: 副業で作っているお問い合わせフォームをコミット直前に点検したいとき
個人でランディングページにお問い合わせフォームを足したけど、フォーム送信処理は普段書き慣れてない領域。書き終わって「動いてはいるけど安全か自信ない」タイミングで /security-review を叩きます。SQLインジェクション、メールヘッダーインジェクション、CSRF(他サイトから勝手にフォーム送信される攻撃)など、フォーム特有の地雷をClaudeが拾ってくれます。私はこのパターンで使う場面が一番多いです。
シナリオ2: 既存サービスに認証機能を足した直後に、認可漏れがないか見たいとき
たとえばユーザー管理機能を新しく追加して、「自分のプロフィールしか編集できないはず」のエンドポイントを作ったとします。ここで /security-review を叩くと、「user_id をURLパラメータから直接読んでいて、他人のIDを送れば他人のデータが書き換えられる構造になっています(IDOR脆弱性)」みたいな指摘が出ます。認可(誰が何をしていいかのチェック)漏れは1人で書いてると気付きにくいので、第三者目線として価値があります。
シナリオ3: PRを上げる前のセルフレビューに使いたいとき
チーム開発で他の人にレビューしてもらう前に、自分で1回潰しておきたい場面。/security-review を叩いてHIGH・MEDIUMだけでも先に直しておくと、レビューで「セキュリティ系の基本的な指摘」を受けずに済みます。これは「他人にレビューを依頼する前のマナー」みたいな使い方です。
初心者が踏みやすい落とし穴
- 静的解析ツールの代わりにはならない。CodeQLやSemgrepみたいな専用ツール(コードのパターンを機械的に走査するセキュリティ検査ツール)と違って、Claudeの判断ベースなので漏れも誤検出もあります。「叩いて指摘ゼロ=安全」とは思わないほうが安全です
- 過去のコミットに埋まったシークレットは見つからない。検出対象は「いま書き換え途中の差分」だけ。半年前にうっかり
config.phpにAPIキーを書いて push してしまった事故は、このコマンドでは見つかりません。git secretsやtrufflehogなど履歴スキャン専用ツールが別途必要です - 大きすぎる差分は精度が落ちる。一気に20ファイル書き換えてから叩くと、Claudeのチェックが浅くなりがちです。1機能・1〜数ファイル単位でこまめに叩いたほうが、指摘の精度も読みやすさも上がります
- GitHub Actions経由の「Claude Code Security Review」と混同しない。あちらはPR作成時に自動で走る公式アクション、こちらはローカルのClaude Codeセッションでオンデマンドで叩くもの。役割が別なので、両方併用してOK(自動チェック+手元での即時チェック)
- 似た名前の
/reviewや/code-reviewと混同しない。/reviewはプルリク全体のレビュー、/code-reviewはコード品質(読みやすさ・設計)のレビュー。/security-reviewはセキュリティ特化です。コード品質も気になるなら別途叩く必要があります - 指摘の重要度ラベルを鵜呑みにしない。Claudeが「HIGH」と返してきても、自分のサービスの文脈(公開範囲・扱うデータ・想定攻撃者)で考えると「LOWでいい」ケースもあります。逆も然り。最終判断は自分の責任で
- コミット済みファイルだけ修正したいときには使えない。「過去にコミットしたファイルを念のため見てほしい」場合は、いったん該当ファイルを読み込んで「このファイルにセキュリティ問題ないか見て」と通常チャットで頼むほうが確実です
書き方
/security-review
# コマンドだけそのまま叩く。後ろに何も書き足さない
やってみるとこうなる
入力
/security-review
出力例
Reviewing pending changes on branch feature/contact-form...
## contact_submit.php
[HIGH] SQL injection vulnerability
Line 12: $_POST values are concatenated directly into the SQL string.
Use prepared statements (mysqli_prepare + bind_param).
[MEDIUM] Missing input validation
Line 8: $email is not validated as an email format.
Suggest filter_var($email, FILTER_VALIDATE_EMAIL).
[LOW] Potential XSS in admin view
Line 18: $message is stored without escaping.
Apply htmlspecialchars() when rendering.
Summary: 1 HIGH, 1 MEDIUM, 1 LOW finding.
このページに出てきた言葉
- スラッシュコマンド
- Claude Codeのチャット入力欄で <code>/</code> から始まる単語を打つと動く、専用機能の呼び出し方
- 差分
- 前のコードと今のコードの違いだけを抜き出したもの。Gitで <code>git diff</code> で確認できる
- コミット
- Gitで変更を「ここまで保存」と区切る操作
- リポジトリ
- プロジェクトのファイル一式と変更履歴をまとめて保存する箱。GitHub上で見えるあれ
- ブランチ
- 同じプロジェクトの中で複数の作業を平行して進めるための「枝分かれした作業場」
- シークレット
- APIキー、パスワード、認証トークンなど、外に漏らしちゃいけない文字列の総称
- SQLインジェクション
- 入力欄に細工した文字列を送り込んで、データベースに想定外の命令を実行させる攻撃
- XSS
- クロスサイトスクリプティング。入力値に <code><script></code> を仕込んで他のユーザーのブラウザで悪意のあるプログラムを動かす攻撃
- プリペアドステートメント
- SQL文の「枠」と「中身(ユーザー入力)」を別々にデータベースに渡す仕組み。SQLインジェクションを構造的に防げる
- バリデーション
- ユーザーが入力した値が想定通りの形式(メールアドレスっぽいか、数字か、空じゃないか等)かをチェックする処理
- 認可
- ログインしたユーザーがこの操作をしていいかを判定する仕組み。認証(誰かを確認する)の次の段階
- IDOR
- 安全でない直接オブジェクト参照。URLのID部分を書き換えるだけで他人のデータが見えたり書き換えられたりする欠陥
- CSRF
- ログイン中のユーザーを別サイトから操作して、本人が知らないうちにフォーム送信などをさせる攻撃
- 静的解析ツール
- コードのパターンを機械的に走査して問題を検出する専用ツール。CodeQL、Semgrepなどが代表例