0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🔨47秒でXSS修正!?VS Code版Codexを「他部署から来たベテラン点検員」として使ってみた

0
Last updated at Posted at 2026-08-01

qiita152.png

はじめに

現役のトラックドライバーとして物流の現場で働きながら、PythonとWebアプリケーション開発を独学しているtosane932です。

2026年5月12日に学習を始め、今回で累計学習時間は152時間になりました。

今回は、VS Code版Codexを使って、開発中のFlaskアプリケーションを静的レビューしました。

対象は、🍞ベーカリー店舗向けの売上管理アプリです。(sales_data_app)

  • 商品の登録
  • 日次売上数量の入力
  • 売上ランキングの表示
  • Chart.jsによる可視化
  • Gemini APIによる経営アドバイス
  • PostgreSQLによるデータ管理
  • Dockerによる実行環境構築
  • pytestとGitHub Actionsによるテスト

これまでにも自分でコードを点検してきましたが、今回はCodexにプロジェクト全体を読み取らせ、改善候補を洗い出してもらいました。

結論から書くと、Codexは非常に速く、調査能力も高いと感じました。

一方で、指摘された内容をそのまま一括修正させると、既存機能やデータベースを壊す危険もあります。

Codexは、私にとって次のような存在でした。

現場のことを知らない他部署から転勤してきた、経験豊富なベテラン社員

点検能力は高いものの、何が不具合で、何が意図した仕様なのかは、現場を知る人間が判断する必要があります。

VS Code版Codexを導入

VS CodeへOpenAI公式のCodex拡張機能を導入しました。

Codexは、現在開いているプロジェクト内のファイルを確認し、コードの説明、調査、修正、テスト実行などを行えます。

ただし、最初に次のような指示を出したところ、調査を進められませんでした。

このプロジェクトの構成を確認してください。
ファイルの変更やターミナルコマンドの実行はしないでください。

Codexからは、ターミナルコマンドを使わずにファイル一覧や内容を確認する手段がないため、調査できないと回答がありました。

そこで、読み取り専用のコマンドは許可し、変更操作だけを禁止する形へ修正しました。

プロジェクト構成の確認に必要な、
読み取り専用のターミナルコマンドは実行して構いません。

ただし、以下は禁止します。

- ファイルの作成・変更・削除
- パッケージのインストール
- データベースの変更
- Gitへの変更操作
- アプリケーションの起動

この変更により、Codexはプロジェクト全体を読み取り専用で確認できるようになりました。

Codexへ設定した作業ルール

Codexへ無制限に操作を許可するのは危険だと感じたため、カスタム指示へ作業ルールを追加しました。

作業ルール:

- 私の明確な許可なしに、修正を開始しないでください。
- 最初に、現在確認できる事実、原因候補、修正案、
  影響範囲、必要なテストを説明してください。
- 調査と修正を分け、原則として一度に扱う問題は
  1件だけにしてください。
- 別目的の変更を同じ作業に混ぜないでください。
- Gitのcommit、push、reset、rebaseは、
  明確な許可なしに実行しないでください。
- データベースの作成、削除、マイグレーション実行、
  データ変更は、必ず事前に確認してください。
- ファイルの削除、依存関係の更新、
  本番環境に影響する操作も、必ず事前に確認してください。
- 読み取り専用の調査コマンドは実行して構いません。
- 修正後は、変更ファイル、変更理由、
  影響範囲、確認結果を報告してください。

Codex側の承認設定も、フルアクセスではなく、操作時に承認を求める設定にしました。

カスタム指示は作業方針であり、強制的なアクセス制御ではありません。

そのため、設定と指示の両方で制限をかけています。

プロジェクト全体を静的レビュー

Codexへ、次の観点でプロジェクト全体の静的レビューを依頼しました。

このプロジェクト全体を読み取り専用で点検してください。

次の観点で、改善候補を報告してください。

- 明らかな不具合
- セキュリティ
- 保守性
- テスト不足
- 不要ファイルや古い処理
- READMEと実装の不一致

条件:

- ファイルの作成・変更・削除はしない
- データベースを変更しない
- Gitの変更操作をしない
- アプリやテストはまだ実行しない
- 確認できた事実と推測を分ける
- 重要度を「高・中・低」で分類する
- 各項目に、根拠となるファイル名と該当箇所を示す

その結果、合計18件の改善候補が報告されました。

主な内容は次のとおりです。

重要度:高

  • 空のDBから構築できない可能性があるマイグレーション
  • 動的ランキング表示の保存型XSS
  • 公開環境で認証なしにデータを更新できる
  • 売上日と商品の年月・販売状態を検証していない
  • .envのファイル権限

重要度:中

  • Gemini APIを認証なしで連続実行できる
  • 不正入力が500エラーや成功扱いになる
  • 同日・同一商品の重複をDB側で防止していない
  • 重要処理のテストが不足している
  • 商品名だけで売上を集計している
  • Chart.jsのバージョンが固定されていない
  • コンテナがrootユーザーで動作する
  • 開発用依存関係が本番にも含まれる

重要度:低

  • 年選択が2026年に固定されている
  • READMEなどから参照されていない画像や動画
  • ローカル生成物や旧資料
  • JSON-LDに仮URLが残っている
  • CIとRenderデプロイ条件の関係が不明確

ファイル名や該当行、確認できた事実、推測される影響、改善案まで整理されていました。

内容の多さには驚きましたが、ここで全項目の修正を依頼するのは危険だと判断しました。

AIの指摘をそのまま信じない

Codexの最初のレビューでは、.envの権限が重要度「高」と評価されていました。

しかし、再確認を依頼すると、Codexは次の点を追加調査しました。

  • /home/tosaneの権限は0750
  • .envはGit管理対象外
  • .envはDockerイメージにも含まれない
  • Renderではローカルの.envを直接使用しない
  • 単一ユーザー環境では追加リスクが小さい

その結果、Codex自身が、重要度を「高」から「低〜中」へ修正しました。

これは、最初の回答をそのまま採用せず、再確認させる重要性を示しています。

AIの回答は、丁寧に書かれていても、必ず正しいとは限りません。

今回は次の流れで確認しました。

  1. プロジェクト全体を静的レビューする
  2. 重要度「高」の項目だけを再確認する
  3. 再現条件と現在の実害を分ける
  4. 修正前に必要な仕様を確認する
  5. 最初の修正対象を1件だけ選ぶ

最初に保存型XSSを修正

18件のうち、最初の修正対象として、ダッシュボードの動的ランキング表示にある保存型XSSを選びました。

選んだ理由は次のとおりです。

  • 修正範囲を1ファイルに限定できる
  • DBや認証設計へ影響しない
  • 通常の商品名表示を維持できる
  • セキュリティ上の効果が明確
  • 手動で動作確認しやすい

問題となったコードは、APIから取得した商品名をHTML文字列へ埋め込んでいた部分です。

<div class="prod-name">${item[0]}</div>

作成したHTML文字列は、最後にinnerHTMLへ代入されていました。

rankContainer.innerHTML = htmlContent;

item[0]には、利用者が登録した商品名が入ります。

そのため、商品名にHTMLやイベント属性が含まれていると、ブラウザが商品名を文字列ではなくHTMLとして解釈する可能性がありました。

初回表示ではJinja2の自動エスケープが働いていましたが、Fetch APIで取得した後の動的ランキング更新では、JavaScript側でinnerHTMLを使用していました。

修正前にCodexへ設計だけを依頼

いきなりコードを変更させず、まず修正方法だけを説明してもらいました。

重要度「高」のうち、
商品名の保存型XSS対策だけを扱ってください。

まだファイルは変更しないでください。

以下を整理してください。

1. 修正が必要な正確なコード箇所
2. innerHTMLを使わずに同じ表示を実現する方法
3. 変更対象ファイル
4. 既存のランキング表示への影響
5. 商品名に日本語・記号・HTML文字列が
   含まれる場合の期待結果
6. 修正後に必要なテスト

AI返答の表示部分、CSP、認証、DB、
その他の改善は今回は扱わないでください。

Codexからは、次の方針が提案されました。

  • innerHTMLを使用しない
  • document.createElement()で要素を作成する
  • 商品名はtextContentへ設定する
  • DocumentFragmentで複数行をまとめて追加する
  • 既存のCSSクラスとDOM構造を維持する
  • 空データ表示もDOM APIで生成する

修正対象は、templates/dashboard.htmlの1ファイルだけで完結すると説明されました。

Codexへ修正を許可

修正範囲を確認した後、次の条件で実装を許可しました。

商品名を表示する動的ランキング部分の
保存型XSS対策だけを実装してください。

条件:

- 変更対象は templates/dashboard.html のみ
- ランキング更新処理だけを変更する
- AI返答、Chart.js、API、CSS、
  バックエンド、DBには触れない
- 既存のクラス名とDOM構造を維持する
- innerHTMLによるランキング生成をやめ、
  DOM APIとtextContentを使用する
- Gitのcommit、pushは行わない
- テストやアプリ起動はまだ行わない

変更後に、次の内容を報告してください。

1. 実際に変更した範囲
2. 変更前後の違い
3. 指示外の変更がないこと

Codexは、この変更を約47秒で完了しました。

修正後のコード

商品名は、次のようにtextContentへ設定されました。

const productName = document.createElement('div');
productName.className = 'prod-name';
productName.textContent = item[0];

textContentは、渡された値をHTMLとして解釈しません。

たとえば、次の商品名が登録されていた場合でも、

<b>メロンパン</b>

b要素を生成して太字にするのではなく、文字列として扱います。

ランキングの生成処理では、各要素をDOM APIで作成します。

const rankingItem = document.createElement('div');
rankingItem.className = 'ranking-item';

const rankBadge = document.createElement('div');
rankBadge.className = 'rank-badge';

if (rank <= 3) {
    rankBadge.classList.add(`rank-${rank}`);
}

rankBadge.textContent = String(rank);

数量と単位もHTML文字列ではなく、個別の要素として作成します。

const productQuantity = document.createElement('div');
productQuantity.className = 'prod-qty';
productQuantity.append(
    document.createTextNode(String(item[1]))
);

const productUnit = document.createElement('span');
productUnit.className = 'prod-unit';
productUnit.textContent = '';

productQuantity.append(productUnit);

最後に、作成した要素をまとめて追加します。

rankingItem.append(
    rankBadge,
    productName,
    productQuantity
);

fragment.append(rankingItem);

古いランキング表示は、replaceChildren()で削除します。

rankContainer.replaceChildren();

既存のCSSクラスとDOM構造は維持したため、見た目を変えずに表示処理だけを安全な方法へ変更できました。

手動で動作確認

修正後、実際に商品を登録し、売上数量を入力して確認しました。

ローカル環境とRender本番環境では使用しているデータベースが別のため、Render側でも同じ商品名を改めて登録し、スマートフォンから動作確認しました。

通常の商品名

メロンパン

通常どおり表示されました。

HTMLタグを含む商品名

<b>メロンパン</b>

太字として表示されず、HTMLとして解釈されることなく、文字列のまま表示されました。

日本語・記号を含む商品名

あんぱん <限定> & コーヒー

<>&を含めて正常に表示されました。

商品登録、売上数量入力、ダッシュボードのランキング更新にも異常はありませんでした。

Render公開デモをスマートフォンで最終確認

修正後は、Render上の公開デモをスマートフォンから操作し、実際に次の商品名を登録しました。

  • <b>メロンパン</b>
  • あんぱん <限定> & コーヒー

その後、日次売上数量を入力し、ダッシュボードのランキングとグラフへ反映されることを確認しました。

結果として、HTMLタグは実行・装飾されず文字列として表示され、<>&などの記号も欠落しませんでした。

また、既存の売上入力、ランキング、グラフ表示にも異常はありませんでした。

差分を確認

Codexからは、変更されたファイルはtemplates/dashboard.htmlだけだと報告されました。

人間側でもgit diffを使用し、変更範囲を確認しました。

git diff -- templates/dashboard.html

git diffの表示にはlessというページャーが使用されます。

表示画面から戻る場合は、qを押します。

q = quit

これはターミナルを終了する操作ではなく、差分の閲覧画面を閉じて、通常の入力状態へ戻る操作です。

Codexは実務で使えるのか

今回のCodexの回答は、単なるコード生成ではありませんでした。

  • プロジェクト全体の構成確認
  • READMEと実装の比較
  • セキュリティ上の問題点の抽出
  • 根拠となるファイルと行の提示
  • 事実と推測の分離
  • 再現条件の整理
  • 既存機能への影響確認
  • 必要なテストの提案
  • 指示された範囲だけの修正
  • 修正後の変更内容の報告

ここまでを短時間で実施できた点は、非常に強力だと感じました。

数年前であれば、人間がファイルを一つずつ確認し、根拠となる行番号を記録し、改善案を報告書へまとめる必要がありました。

静的解析ツールやリンターは以前から存在しましたが、プロジェクトの文脈を含め、日本語で理由や影響範囲まで説明する部分には、多くの時間が必要だったと思います。

ただし、Codexが提示した18件を一括修正させるのは危険です。

たとえば、次の問題は、コードを変更する前に業務仕様の決定が必要です。

  • 過去日の売上修正を許可するか
  • 販売終了商品の過去実績を修正できるか
  • 公開デモを誰でも操作可能にするか
  • 認証を必須にするか
  • 空DB向けマイグレーションをどう修復するか
  • 既存のRender DBへどう影響するか

技術的に安全そうな修正でも、現在のアプリの目的を壊す可能性があります。

他部署から来たベテラン点検員

今回、Codexを使って感じたことを、物流現場にたとえると次のようになります。

Codexは、現場のことを知らない他部署から転勤してきた、経験豊富なベテラン社員

設備や手順の危険箇所を見つける能力は高く、報告も速い。

しかし、その現場でなぜ現在の運用をしているのか、何を優先しているのか、例外対応が必要なのかまでは分かりません。

そのため、Codexから指摘を受けた人間側には、次の判断が必要です。

  • 本当に不具合なのか
  • 意図した仕様なのか
  • 将来対応する課題なのか
  • 今すぐ直すべきなのか
  • どの範囲なら安全に変更できるのか
  • 修正によって別の業務を壊さないか

今回、Codexへ修正を依頼するまでに、次の手順を踏みました。

  1. 読み取り専用で全体を点検
  2. 重要度「高」の指摘を再確認
  3. 誤評価された項目の重要度を修正
  4. 修正対象を保存型XSSの1件に限定
  5. 修正前に設計と影響範囲を確認
  6. 変更対象を1ファイルに限定
  7. Codexへ実装を許可
  8. git diffで差分を確認
  9. ローカル環境で対象商品を登録し、売上入力とダッシュボード表示を確認
  10. 変更をコミットし、GitHubへpush
  11. Renderへのデプロイ完了を確認
  12. Render本番環境ではローカルDBと別データのため、同じ対象商品を改めて登録
  13. スマートフォンから売上入力、ランキング、グラフ表示を確認
  14. ローカル環境とRender本番環境の両方で異常がないことを確認

Codexがコードを変更した時間は約47秒でした。

しかし、その47秒を安全にするために、人間側が調査結果を読み、仕様を考え、修正範囲を決める必要があります。

AIに任せる部分と、人間が判断する部分

今回の経験から、役割を次のように整理しました。

Codexへ任せやすい部分

  • プロジェクト内のファイル調査
  • コード上の問題候補の抽出
  • 根拠箇所の提示
  • 修正案の比較
  • 限定されたコード変更
  • 変更内容の報告
  • テスト候補の提案

人間が判断する部分

  • アプリの目的
  • 業務仕様
  • 優先順位
  • 許容できるリスク
  • 公開デモの運用方針
  • DBや本番環境への変更判断
  • どの指摘を採用し、どれを見送るか
  • 最終的な動作確認と出荷判断

Codexは、指示どおりに素早く作業してくれます。

その一方で、指示が曖昧なままフルアクセスを与えたり、「全部修正してください」と依頼したりすると、大きな事故につながる可能性があります。

速い作業者ほど、作業範囲と停止条件を明確にする必要があります。

まとめ

今回、VS Code版Codexを使い、Flaskアプリケーションの静的レビューと保存型XSS対策を行いました。

最終的に実施した変更は、templates/dashboard.htmlの動的ランキング生成処理だけです。

  • innerHTMLによるHTML文字列生成を廃止
  • createElement()でDOM要素を生成
  • 商品名をtextContentへ設定
  • 既存のCSSクラスとDOM構造を維持
  • 日本語、記号、HTML文字列を含む商品名で手動確認
  • 通常の商品登録・売上入力・ランキング表示に異常なし

Codexの調査能力と作業速度は、実務でも十分に活用できる可能性があると感じました。

ただし、AIが見つけた問題をすべて修正することが、正解とは限りません。

大切なのは、AIの回答をそのまま採用することではなく、次の流れを守ることです。

調査する
再確認する
仕様を決める
変更範囲を限定する
差分を確認する
実際に動作確認する

Codexは、非常に速く優秀な作業担当者です。

一方で、何を直し、何を直さず、いつ出荷するかを決めるのは、人間の役割だと感じました。

今回で累計学習時間は152時間です。

今後も、AIへコードを丸投げするのではなく、原因、影響範囲、修正理由を自分の言葉で説明できる状態を目指して開発を続けます。

関連リンク

GitHub

公開デモ

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?