AI・セキュリティ / 技術研究の解説

動いたコードが、安全とは限らない。AIの「正解」をどう見抜く?

テストは緑。画面も動く。それでも、名前の一文字や利用者の違いで壊れることがあります。確かめる条件を一つ増やすと、「動いた」の先を調べられます。

4資料を参照読む目安 6分2026.10.30制作・運営:ENGINEERING BRIDGE
AI生成のイラスト · 記事のテーマを表現しています
この記事の目次

「動いた」の中に、何を確かめたかが隠れている

名前を入れると会員情報が出る。自分の名前では問題なく動いたので、AIが作った検索処理をそのまま使いたくなった。でも、名前にアポストロフィが一つ入ったら止まるとしたら? 入力例が一つ増えるだけで、「完成」の意味は変わってきます。

機能のテストは、思った入力で望む結果が出るかを調べます。安全性を調べるときは、想定外の入力や、見せてはいけない相手、触らせてはいけない範囲にも目を向ける。同じ「動くコード」の話でも、問いが違うんですね。

研究が調べたのは、文章の上手さよりコードの中身

Pearce氏らの研究は、当時のCopilotへ安全性に関わる場面を与え、危険なコードが提案され得ることを調べました。生成されたコードが整っていることと、安全な処理であることが、別の問題だと分かる研究です。[1]

さらにPerry氏らは、47人にPython・JavaScript・Cを使う5種類の課題へ取り組んでもらいました。AIを利用できる条件では脆弱性が増える場面があり、それでも利用者は安全だと思いやすかったと報告しています。見た目の納得と、実際に確かめた結果がずれる点は、気になりますよね。[2]

ただし「AIを使うほど必ず危険」という一本道にもなりません。Sandoval氏らの学生58人の研究は、Cで買い物リストの連結構造を作る設定で、安全性への影響は小さいと報告しました。言語、課題、利用者、支援の受け方が違えば、観察される結果も変わる。ここは両方を残して読みたいところです。[3]

悪意がなくても、名前の一文字で境界が見える

最初の名前検索を、もう少し近くで見てみます。SQLというデータベースへの依頼文を、利用者が入力した名前と文字列でつなぐと、名前の中の記号まで依頼文の一部として読まれることがあります。たとえば架空の名前 O'Reilly の引用符が、文字列の区切りとぶつかる。これは、入力データと命令の境界が混ざる一例です。

対処は「変な名前は禁止」に寄せるより、値を別の引数で受け取る、DBの呼び出し機能を使うこと。下の資料では、SQLの形を固定し、名前を別の引数に分けています。同じ考え方でも、Python、Java、JavaScriptや使うDBで書式が違うので、製品の正しい呼び出し方を確認します。

問い合わせ窓口に置き換えると、「この名前の人を探して」という仕事の型と、「探す名前」という記入欄を分ける感覚です。名前にどんな記号があっても、窓口の仕事そのものは変えない。その役割を、パラメーターを受け取るAPIに担ってもらいます。人が毎回、入力中の記号を数える方法より、境界を保つ場所が明確になるでしょう。

それでも、入力を分けた後に全会員の情報を返していたら、別の問題が残ります。自分の画面で検索できたことを喜ぶのと同時に、別の利用者から同じ結果が見えてよいかを考える。この問いの切り替えが、安全性の確認を、単なる「変な入力を弾く作業」から広げます。

Asare氏らは、人間が脆弱性を入れた場面を起点としてCopilotの提案を比較しました。ここから持ち帰れるのは、人間のコードも比較の対象になるということです。AIか人間かのラベルだけで通すより、今の入力と処理がどこで混ざるかを具体的に読む方が、直す場所へ近づけるでしょう。[4]

さらに検索結果を返す前には、「この利用者へ、その会員情報を見せてよいか」という確認も要ります。入力を安全に渡せたからといって、閲覧の権限まで決まるわけではない。入力、操作できる範囲、返す情報。この三つを別々の問いにすると、確認を忘れにくくなります。

つまり、出力されたコードに「安全にして」と追記するだけで終わらず、安全という言葉を、試せる条件へほどく。自分の名前、記号のある名前、存在しない名前、別の利用者の情報。何を返すべきかを先に書けば、AIにも同じ検査条件を渡せます。

しくみを、手元の例で

入力した名前を、命令と別の場所へ渡す

名前は、どちらも O'Reilly
SELECT name FROM people WHERE name = 'O'Reilly'
                                      ↑
                         名前の一文字が、区切りに混ざる
  1. 1
    SQLの前半

    引用符までを文字列で作る

  2. 2
    名前を追加

    入力にも引用符がある

  3. 3
    混ざる境界

    値の一文字がSQLの構文に入る

説明用の例です。研究の実測データや、あなたの環境の測定結果ではありません。ボタンで見る条件を切り替えられます。

まず練習用データで、一つだけ境界を増やす

手元でPythonを動かせるなら、外へ通信しない一時的なSQLiteデータベースで試せます。下の例は、記号を含む架空の名前を登録して検索するだけ。既存のDBへ接続せず、実名も秘密も使いません。期待する結果は、その一件だけが返ることです。

コードをAIへ見てもらうなら、「この処理は、どの入力とどの権限を試していないか」と問いを絞るのも一案です。出てきたテストは自分でも読んで、値の受け渡しと、結果を見る相手を確認する。AIの答えを、もう一度AIが褒めたことを検証結果にしないのがコツでしょう。

import sqlite3
con = sqlite3.connect(':memory:')
con.execute('CREATE TABLE demo(name TEXT)')
name = "O'Reilly"
con.execute('INSERT INTO demo VALUES (?)', (name,))
rows = con.execute('SELECT name FROM demo WHERE name = ?', (name,)).fetchall()
print(rows)  # 架空の名前の一件だけが返る
con.close()

採用する前に、説明できる三行を残そう

確認の最後に、「外から来る値は何か」「誰が何をできるか」「失敗したらどう止めるか」を三行にしてみます。途中の一行が書けなければ、そこが次に調べる場所です。分からないコードを丸ごと採用するより、小さく戻れる形で受け取れます。

研究の結果が違っても、この確認は無駄になりません。昔のモデルの数字を今のコードへ貼る代わりに、今の自分が守りたい条件をテストにする。動いたことを喜びながら、もう一つの入力でも確かめられたら、「使えそう」が少し具体的になるはずです。

研究の補足と、よくある疑問

このSQLiteの例だけで安全性を確認できる?

ここで確かめるのはパラメーターとして値を渡す一例です。権限、セッション、エラー処理、依存ライブラリ等の試験は別に必要です。実データや本番のDBへそのまま接続する例ではありません。

反対の結果があるなら、どちらを信じればよい?

PerryらとSandovalらでは言語や課題、参加者、支援条件が異なります。単一の脆弱性率へまとめず、何を検証する研究だったかを照合して、自分のテストを決めます。[2][3]

出典と確認した範囲(4資料)

出典と、読み取れる範囲

原著の公開要旨・取得できた本文部分・研究レビューと、仕様を確認する公式資料を照合しています。対象と比較条件が違う結果を一つの効果へ合算せず、手元の操作例は編集上の説明例として区別します。確認範囲は資料ごとに示しています。

  1. セキュリティ実験

    対象・方法:当時のCopilotへ脆弱性に関係するシナリオを与え、生成プログラムを評価。

    主な結果:危険なコードが生成され得ることを示す。

    限界:プロンプト・対象・旧モデルに依存。人間との協働全体の効果や現在の発生確率へ一般化しない。

    確認した範囲

    IEEE版の書誌と著者のarXiv公開要旨を確認。2025年の同題再掲を独立研究として重複計上しない。 確認日:2026-10-29

    取得できた書誌で撤回・懸念通知は確認されていません。出版社の履歴を網羅した監査ではありません。

  2. セキュリティ実験

    対象・方法:47人、Python・JavaScript・Cの5種類のセキュリティ関連課題。

    主な結果:AI利用条件で脆弱性の増加と安全性への過信を観察した。

    限界:Codex系の当時の支援と課題設定。現在のすべての生成コードの脆弱性率を示すものではない。

    確認した範囲

    2022年arXiv版の本文冒頭・結果の説明と、2023年CCS版の書誌を照合。版差の全面監査は未実施。 確認日:2026-10-29

    取得できた書誌で撤回・懸念通知は確認されていません。出版社の履歴を網羅した監査ではありません。

  3. セキュリティ実験arXiv公開版を参照。刊行版との対応・版差は全面照合していません。

    対象・方法:学生プログラマー58人。Cの単方向連結リストによる買い物リスト実装。

    主な結果:この設定では重大な安全性の悪化が小さいと報告。

    限界:特定の低水準C課題。Perryらとは参加者・言語構成・課題・支援条件が異なる。原著は2022年投稿、確認した版は2023年改訂。

    確認した範囲

    原著の公開要旨を確認。本文全体の精読・実験の追試は未実施。 確認日:2026-10-29

    取得できた書誌で撤回・懸念通知は確認されていません。出版社の履歴を網羅した監査ではありません。

  4. セキュリティ実験

    対象・方法:人間が脆弱性を入れたコードを起点に、Copilotの提案を比較する評価。

    主な結果:既知の人間の誤りを起点とする比較で、生成コードの安全性を調べる。

    限界:任意の新規開発全体の危険率ではない。人間も誤ることと生成結果の検証不要は別。

    確認した範囲

    2022年arXiv版の研究設定の本文と、2023年誌上版の書誌を照合。誌上版全文の版差照合は未実施。 確認日:2026-10-29

    取得できた書誌で撤回・懸念通知は確認されていません。出版社の履歴を網羅した監査ではありません。

この記事は複数文献を照合した編集記事です。既存研究を照合し、結果と条件を紹介しています。研究が同じ参加者を含む可能性があるため、文献間の人数を足していません。本文の行動提案・未来のシナリオは編集上の整理です。

文献の選び方・撤回と訂正への対応 →