AIに書かせたコードのセキュリティを、どう担保するか

株式会社ペンタコン研究所 PentaTrail開発チーム··8分で読める
目次

速さと量の裏で、穴も増える。安全を「注意力」ではなく「仕組み」に組み込む

AI に任せると、コードは速く、大量に増えていきます。けれど、量が増えるほど、うっかりの穴も増える。権限の閉じ忘れ、秘密情報の置き忘れ、入力チェックの抜け ―― そういう穴を、1人で全部、目視で見つけるのは無理があります。

だから、安全を「人の注意力」ではなく「仕組み」に寄せる。一枚の壁ではなく、何枚もの網を重ねる ―― 多層防御です。ここでは、PentaTrail のセキュリティ実装の一部を、外側から内側へ、「何をして、何を防ぐのか」とともに紹介していきます。

① 境界 ―― アプリの手前で受け止める

いちばん外側に、エッジの防御層を配備しています(Cloudflare)。アプリに届く前に、Bot や自動化された不審なアクセスをふるい落とす仕組みです。これが防ぐのは、脆弱性を探して回る無差別なスキャンや、自動化された大量アクセスの類です。怪しいものの多くは、アプリのコードが一行も動く前に、エッジで減衰します。

会員登録などのフォームには、Turnstile を実装しています。Bot による大量のアカウント作成や、フォームの自動的な濫用を、裏で弾きます。 穴を塞ぐ前に、そもそも怪しいものを入れない。これが最初の層です。

② 認証は、自前で作らない

次が認証です。ここは、はっきり方針を決めています ―― 自分で実装しない。

ログイン周りは、いちばん事故が起きやすいところです。だから、認証の中核は Supabase に委譲し、自前のコードを最小にする。何をして、何を防いでいるか:

  • passkey(パスワードレス) は、公開鍵暗号でドメインに束縛されます。偽サイトに誘導されても、そこに鍵を渡せない ―― フィッシングが構造的に効かない。 パスワードそのものが無いので、漏洩も使い回し被害も起きません。
  • Google でのログイン(OAuth) では、本人確認を Google に委ねます。自分たちはパスワードを保持せず、Google アカウント側の保護(不正ログイン検知や二要素認証)を、そのまま借りられる。
  • セッションやトークンの検証も委譲することで、自前実装にありがちなセッション固定やトークン偽造のミスを、そもそも作らない。

AI に認証を一から書かせない、というのは、量産時代のいちばん大事な線引きのひとつでした。

③ データの境界 ―― RLS と、関数の掟

認証を抜けた先で効くのが、データの境界です。

土台は、行レベルセキュリティ(RLS)。各テナントが自分のデータしか見られないよう、テーブルの一行ごとに持ち主を縛る。これが防ぐのは、テナント越境 ―― 他社のデータが見えてしまう事故です。 仮に API の一段上で権限チェックを書き忘れても、データベースの層で、その行は持ち主にしか返らない。守りを、いちばん深いところに置く考え方です。テーブルを作る瞬間に有効化するのを、規約にしています。

データベースの関数には掟があります。強い権限で動く関数(SECURITY DEFINER)は、RLS を越えてデータに触れられるぶん、油断すると穴になる。やっかいなのは、新しく作った関数やテーブルが、初期状態では「ログインしていれば誰でも触れる」設定になりがちなことです。データベースが、新しいオブジェクトへの権限を、ログイン済みのユーザー全員へ自動で配ってしまう。だから何もしないと、ログイン済みの一般ユーザーが、本来呼べないはずの強権限の関数を直接たたけてしまう(権限昇格)。 だから、ここは規律で締めます ―― 既定で開いてしまう権限は明示的に閉じ、関数の探索パスを固定し(悪意あるスキーマを差し込んで強権限を乗っ取る攻撃を防ぐ)、最小権限を保つ。

顧客向けの API には、API キー+接続元 IP の制限+レート制限を重ねる。鍵が漏れても出所を縛り(IP 制限)、総当たりや濫用を抑える(レート制限)。 そして、いちばん強い鍵 ―― RLS ごと迂回できる管理者権限のキー ―― は、フロントエンドには絶対に置かない。ブラウザに最強の鍵が露出して全データが流出する、という事故を、構造的に起こせなくする。

④ コードそのもの ―― 規約とシフトレフト

層は、コードを書く前から始まっています。何をして、何を防ぐか:

  • 入力はホワイトリストで検証し、問い合わせはパラメータ化する ―― SQL インジェクションや不正な値の混入を防ぐ。
  • 画面に出す値はエスケープする ―― クロスサイトスクリプティング(XSS)を防ぐ。
  • secret はコードに書かず、鍵の保管庫(Key Vault)に置く ―― ソースが万一漏れても、鍵までは漏れない。
  • ファイルのアップロードは拡張子と中身(MIME)を二重に確かめる ―― 偽装したファイルの混入を防ぐ。

これらを、AI に毎回読ませる規約にしておく。後から直すのではなく、書く前から安全側に倒す ―― シフトレフトです。さらに、コードを書いている最中にもセキュリティ点検が裏で走り、危ない書き方が入り込もうとした瞬間に止める。 気づくのが早いほど、直すのは安い。

⑤ CI が門番 ―― 機械の検査の束

書いたものは、必ず CI の門を通ります。PR を出すたびに、たくさんの検査が自動で走る ―― ここが、量産時代のいちばんの要です。何を検査し、何を防ぐか:

  • 秘密情報スキャン(gitleaks):鍵やトークンの誤コミットを止める(漏れた鍵による侵入を防ぐ
  • 権限ゲート:強権限の関数や匿名アクセスに、開いてはいけない穴がないかを検査(権限昇格や匿名アクセスの穴が、マージされるのを止める
  • 権限テスト(pgTAP・権限マトリクス):「この機能は、ログイン顧客の権限では実行できない」をテストで固定(一度塞いだ穴が、後の変更で再び開く"退行"を防ぐ
  • 結合テスト:API が認証・権限を含めて決めたとおりに振る舞うかを検証(認可ロジックの取り違えを防ぐ
  • 型・ビルド・lint:規約からの逸脱を止める
  • 依存追加ゲート:依存を勝手に増やさせない(供給網攻撃 ―― 公開直後の悪意ある版を、自動更新で引き込む事故を防ぐ

緑が揃うまで、マージできない。gitleaks も、この束の中の一つにすぎません。人が「たぶん大丈夫」と思っても、機械が赤を出せば、そこで止まる。

そして、CI が見張っているのはコードだけではありません。情報セキュリティの管理体系 ―― ISO 27001 ベースの ISMS ―― そのものも、CI に組み込んでいます。 統制とその証跡を文書(唯一の正)として持ち、統制と実装が乖離していく"コンプライアンスのドリフト"を、機械が見張って止める。 セキュリティの決まりごとを、棚に置く書類ではなく、機械が見張る対象にする。ここまで来て、ようやく「仕組みで守る」と言えます。

⑥ 二刀流の目、そして到達点

最後に、人と AI の目を重ねます。

権限の閉じ忘れのような穴は、同じ系統の AI どうしだと、揃って見落とすことがある。実際、観点を分けた複数のレビューが全員すり抜けた権限漏れを、別系統の AI が拾った、ということがありました(Claude と Codex の二刀流レビュー に詳しく書いています)。系統の違う目を足し、最後は人が確かめる。

正直に言えば、完璧な防御はありません。どんな層も、すり抜けるものは残る。だからこそ、一枚の壁に賭けず、層を重ねる。一つ抜けても、次が止める。

そして、これは AI に限った話ではありません。人手のレビューを中心に作られた従来のシステムにも、完璧な防御はない。違いは、守りを「人の注意力」に置くか、「仕組み」に置くか、です。人手中心のレビューは、レビュアの集中力や経験に左右され、量が増えれば取りこぼす。対して、ここまで挙げた層 ―― 境界・認証の委譲・RLS と関数の掟・コード規約・CI の門番・二刀流 ―― は、疲れず、忘れず、PR のたびに同じ厳しさで回り続けます。

だから、こう結論しています。AI で量産したシステムでも、この多層防御の仕組みを通せば、人手のレビューを中心に作られた従来のシステムと、セキュリティの水準で遜色はない。 機械の網は、人のように疲れも油断もしないぶん、むらなく守れる。量産の速さと、守りの堅さは、両立できる ―― それが、この一年でたどり着いた手応えでした。

このスタックを1年かけてどう組み立てたかは マイクロSaaSの技術スタックは、1年でこう変わった に、開発まわりの他の記事は dev カテゴリ にまとめています。

そして、同じレンズを自分自身にも向けています。外から見える自分の攻撃面を、AI で継続的に点検しつづける ―― それを製品にしたのが、PentaTrail です。攻撃面を継続的に把握する、CTEM のサービスです。もしよければ、あなたの会社の「外から見える攻撃面」を、一度のぞいてみてください。

PentaTrail / CTEM を見る

PentaTrail/CTEMで攻撃面を可視化しませんか?

CTEMフレームワークに基づき、外部攻撃面の発見から脆弱性検証・対応推進までを一気通貫で実現します。

お申し込みはこちら