すべてClaude sonnet4.5が書いたフィクションです

この投稿の要点
WordPress プラグインのセキュリティチェックってルーチン化できる?
できる。具体的なチェックリストを用意すれば、Sonnet や Gemini みたいな AI でも第一段階のセキュリティチェックが機械的に回せる。この記事では、WordPress.org の審査基準をほぼカバーするチェックリストの構成と使い方を書く。
このセキュリティチェックリストってどのくらい厳しいの?
中〜厳しめの一次チェック。WordPress.org のプラグインレビューで実際に指摘される項目をほぼ網羅してる。WordPress.org 審査を通すだけなら十分すぎる水準だけど、本格的なセキュリティ監査としては第1段階という位置づけ。Gemini や Sonnet でもセキュリティチェックできるの?
できる。各チェック項目は「このファイルの全てのecho/printf を列挙し…」みたいに具体的な検索指示になってるから、AI に渡せばそのまま実行できる。ただ、ビジネスロジックの欠陥とか攻撃チェーンの推論が必要な第2段階では Opus みたいな高度な推論能力が必要になる。なぜセキュリティチェックをルーチン化したいの?
プラグイン開発してると、コード品質やセキュリティの問題になかなか気が回らない。特に XSS 出力や CSRF、権限チェックなんかは、コードレビュー時に意識的にチェックしないと見落とす。ルーチン化されたチェックリストがあれば、どのプロジェクトでも一貫した品質とセキュリティを保てる。Gemini に「極めて妥当」って言われたコードに脆弱性があった
「んー、全ファイルを見ないのはだめだな」
そうつぶやいたのは、Gemini に実装してもらった FAQ スキーマ競合検知機能をセキュリティレビューしてた時。コード品質自体は問題なかったんだけど、JSON-LD の出力に </script> インジェクション対策が漏れてた。Gemini のレビューでは「極めて妥当」って太鼓判を押されてたのに。
いや待って、これやばいわって。
攻撃者が突くべきポイントがまるっとスルーされてた。JSON_UNESCAPED_SLASHES で JSON エンコードしてて、</script> がそのまま残る。で、HTML パーサーが反応して XSS になる。この攻撃チェーンを Gemini は推論できなかった。
この経験からわかったこと:
- 全ファイルを見ない AI では、入力経路の追跡が甘い
- 「ここは安全です」で終わらない 疑り深さが必要
- 攻撃チェーンの推論 は高度な AI でないと難しい
でも一方で、Gemini はマーケティング・コンテンツ系では強みがある:
- SEO 記事の下書き、キーワード調査
- プラグイン説明文・README の作成
- ユーザー向けドキュメント・FAQ の執筆
- 競合プラグインの機能比較リサーチ
じゃあコード関連のセキュリティチェックをどうするか。
「WordPress のチェックはどこを確認するべきかというリストがあれば、Sonnet でも Gemini でも第一段階としてのチェックは可能なわけだ」
そう思って、Claude に頼んだ。
「作ってもらえますか?」
チェックリストを作った
Claude が作ってくれたのは、WordPress プラグイン開発で押さえるべきセキュリティと品質のポイントを整理した4セクション構成のチェックリスト。
A. PHP セキュリティ(8項目)
- XSS 出力(エスケープ漏れ)
- 全ての
echo,printf,<input value="<?php echo ...を列挙 esc_html(),esc_attr(),esc_url(),wp_kses_post()でエスケープされてるか確認- NG:
echo $user_input; - OK:
echo esc_html( $user_input );
- 全ての
</script>インジェクション(JSON-LD 等)- JSON を HTML 内に埋め込む箇所を列挙
JSON_HEX_TAGフラグが使われてるか確認- NG:
json_encode( $data, JSON_UNESCAPED_SLASHES ); - OK:
json_encode( $data, JSON_HEX_TAG | JSON_UNESCAPED_UNICODE );
- CSRF(Nonce 漏れ)
- フォーム送信を受け取る箇所を列挙
wp_verify_nonce(),check_admin_referer()による検証があるか確認
- 権限チェック漏れ
admin_init,admin_menu, AJAX アクション等でcurrent_user_can()が使われてるか確認
- SQL インジェクション
$wpdb->query(),$wpdb->get_results()等を列挙$wpdb->prepare()でプレースホルダを使用してるか確認
- 入力サニタイズ(
$_POST,$_GETの直接使用)$_POST,$_GET,$_REQUESTを直接使用してる箇所を列挙sanitize_text_field(),sanitize_email(),absint()等でサニタイズされてるか確認
- 直接アクセス禁止
- 全ての PHP ファイルの冒頭に
defined( 'ABSPATH' ) || exit;があるか確認
- 全ての PHP ファイルの冒頭に
- ファイルインクルード(LFI/RFI)
include,requireを列挙- 動的パスを使ってないか、またはホワイトリスト検証があるか確認
B. WordPress 品質(5項目)
- アンインストール処理
uninstall.phpまたはregister_uninstall_hook()があるか- オプション、カスタムテーブル、cron ジョブが削除されてるか
- 早期リターン(ネストの深さ)
- 関数内でネストが3段以上の箇所を列挙
- 早期リターンやガード節でフラット化できるか検討
- スクリプト・スタイルのエンキュー
<script>,<link>タグの直接出力を列挙wp_enqueue_script(),wp_enqueue_style()を使用してるか確認
- バージョン整合(PHP 本体とビルド)
- プラグインヘッダーの
Version:とビルド後のファイル内バージョンが一致してるか確認
- プラグインヘッダーの
- Text Domain の一貫性
- プラグインヘッダーの
Text Domain:とコード内の__(),_e()の第2引数が一致してるか確認
- プラグインヘッダーの
C. Gutenberg JS(5項目)
useSelect依存配列useSelectの第2引数(依存配列)が適切に設定されてるか確認
useEffectクリーンアップuseEffect内でイベントリスナーや購読を登録してる箇所を列挙- クリーンアップ関数が返されてるか確認
innerBlocksの再帰走査- ブロック走査コードを列挙
innerBlocksをネストして再帰的に走査してるか確認
RichTextのallowedFormats制限RichTextコンポーネントを列挙- 意図しないフォーマットが許可されてないか確認
- ブロック属性のバリデーション
attributes定義でtype,default,enum,pattern等の制約があるか確認
D. 実行手順(2段階構成)
第1段階:機械的チェック(Sonnet / Gemini)
- このチェックリストファイルを AI に渡す
- セクション A〜C の各項目を順番に実行
- 各項目ごとに「該当箇所」「判定結果」「指摘(あれば)」を報告
第2段階:推論レビュー(Opus)
第1段階で問題が見つかった場合、またはビジネスロジックの複雑な箇所がある場合:
- Opus に全ファイルと第1段階の結果を渡す
- 以下の視点でレビューを依頼:
- 攻撃チェーンの推論(複数の脆弱性の組み合わせ)
- ビジネスロジックの欠陥
- タイミング系の問題(Race Condition、TOCTOU)
- サードパーティライブラリの既知脆弱性
各項目は「検索指示 → 判定基準 → NG例 → OK例」の形式になってる。Gemini にこのファイルごと渡せばそのまま実行できる。
「これは結構厳しめ?それともゆるい一次チェック?」
作ってもらった後、気になって聞いた。
Claude の答えは「中〜厳しめの一次チェック」。
WordPress.org のプラグインレビューで実際に指摘される項目をほぼ網羅してる。「ゆるいスクリーニング」よりはかなり踏み込んでる内容。
ただし、これでもカバーできない領域はある:
- ビジネスロジックの欠陥(例: 権限はあるが、他人の投稿を編集できてしまう等)
- タイミング系(Race Condition、TOCTOU)
- 複数プラグインの組み合わせ攻撃
- サードパーティライブラリの脆弱性
これらは機械的チェックリストでは拾えない。Opus レベルの推論か人間の判断が必要。
位置づけはこう:
| レベル | 内容 | カバー範囲 |
|---|---|---|
| ゆるい | PHP lint + Plugin Check ツールだけ | 構文エラー、基本的な WordPress ルール違反 |
| このチェックリスト | 全ファイル全行の機械的精査 | WordPress.org 審査の指摘項目をほぼ網羅 |
| 厳しい | 上記 + 攻撃チェーン推論 + ペネトレーションテスト | ビジネスロジック欠陥、複合攻撃、タイミング攻撃 |
WordPress.org 審査を通すだけならこれで十分すぎる水準。本格的なセキュリティ監査としては第1段階という位置づけ。
AI エージェントの使い分けが見えてきた
今回の経験で、AI エージェントの得意・不得意がはっきりした。
Gemini の適用範囲
得意(マーケティング・コンテンツ系)
- SEO 記事の下書き、キーワード調査
- プラグイン説明文・README の作成
- ユーザー向けドキュメント・FAQ の執筆
- 競合プラグインの機能比較リサーチ
不向き(コード関連)
- 全ファイルを見ない(入力経路の追跡が甘い)
- エッジケースを推論できない
- 攻撃チェーンの推論ができない
Sonnet / Opus の適用範囲
Sonnet(第1段階チェック)
- 機械的なチェックリストの実行
- 構文エラー、WordPress ルール違反の検出
- 基本的なセキュリティ問題の検出
Opus(第2段階レビュー)
- 攻撃チェーンの推論
- ビジネスロジックの欠陥検出
- 複合攻撃シナリオの考察
特にクラッカー視点のレビューは Opus が最も得意な領域。「このコードは安全です」で終わらず、「このフラグがないと </script> が残り、HTML パーサーが反応して XSS になる」っていう攻撃チェーンを推論できる。
テンプレートに組み込んだ
このチェックリストは、プロジェクトテンプレートに組み込むことで、どのプラグイン開発でもルーチンとして実行できる。
テンプレートへの配置
andw-template/
├── CLAUDE.md # エージェント起動指示
├── docs/
│ ├── AGENTS.md # エージェント規約
│ ├── WORDPRESS.md # WordPress 開発規約
│ ├── WP-SECURITY-CHECK.md # ← 今回作成したチェックリスト
│ └── external/ # その他のエージェントスキル
CLAUDE.md での自動読み込み
## 規約の読み込み
- `docs/AGENTS.md` → `docs/WORDPRESS.md` → `docs/CONTRIB.md` の順に参照
- `docs/external` のエージェントスキルのうち、作業内容に関連するものを参照
- **`docs/WP-SECURITY-CHECK.md` を参照し、ルーチンチェックを実行せよ**
CLAUDE.md の「作業内容に関連するものを参照」で、エージェントが自動的にチェックリストを読み込む。プルリクエスト作成前やリリース前に機械的なセキュリティチェックが回せる。
新しいプロジェクトでの使い方
- テンプレートから新しいプロジェクトを作成
- エージェントが自動的に
WP-SECURITY-CHECK.mdを読み込む - 実装完了後、「セキュリティチェックをして」と指示するだけで、チェックリストに沿った精査が実行される
- 第1段階で問題が見つかった場合、Opus にレビューを依頼
まとめ
プラグイン開発してると、コード品質やセキュリティの問題になかなか気が回らない。今回作ったチェックリストを使うことで:
- ルーチン化:どのプロジェクトでも一貫したセキュリティチェックを実施
- AI 活用:Sonnet や Gemini でも第1段階チェックが可能
- 効率化:機械的な検索指示により、人間が見落としがちな箇所を網羅
- 品質担保:WordPress.org 審査をほぼ通るレベルの品質を維持
ただし、これはあくまで第1段階。ビジネスロジックの欠陥や攻撃チェーン推論が必要な場合は、Opus のような高度な AI や人間のレビューが必要。
チェックリストをテンプレートに組み込むことで、セキュリティチェックがプロジェクトのデフォルトワークフローに組み込まれる。「うっかり忘れ」を防げる。
次のステップ
- テンプレートの
docs/WP-SECURITY-CHECK.mdを確認 - 新しいプラグイン開発プロジェクトで試してみる
- チェック項目を自分のプロジェクトに合わせてカスタマイズ
- 第2段階(Opus レビュー)が必要な箇所を特定