BrassCodersは、調査した15個のAI生成Pythonスクリプトのうち2つにおいて、ハードコードされたシークレットを発見しました。これは、大規模言語モデル(LLM)の出力をそのままコピー&ペーストする開発者にとって、具体的なリスクを露呈するものです。この調査結果は、たった一つの誤ったキーやパスワードの混入が、便利なコードスニペットを、バージョン管理や本番環境全体にわたる認証情報の漏洩へと変えてしまう可能性があることを示しています。

テストで判明したこと

最初のスクリプトである token_check.py は、セッショントークンに署名する関数と「そのまま使える例」を含めるよう求めたプロンプトから生成されました。コードを実行可能な状態にするために、モデルはソースファイル内にHMAC署名キーを直接入力しました。

  • 問題: シークレットキーがコードベース内に存在している。
  • リスク: リポジトリへの読み取り権限を持つ人なら誰でもキーを確認でき、そのファイルを取り込むあらゆるデプロイメントがシークレットを継承してしまう。
  • 結果: キーを入手した攻撃者は、有効なセッショントークンを偽造し、認証チェックをバイパスすることができる。

2番目のスクリプト email_sender.py は、SMTP経由でメールを送信する関数を求めるリクエストに対する回答でした。ここでもモデルは、例がすぐに動作するように、実際のパスワードを提供しました。

  • 問題: 関数呼び出しの中でパスワードが平文の文字列として現れている。
  • リスク: パスワードのローテーションにはコードの変更と再デプロイが必要となり、認証情報がそのファイルを使用するすべての環境に拡散してしまう。
  • 結果: パスワードがソース管理、ログ、またはコンパイルされたパッケージから収集される可能性があり、攻撃者にメールサーバーへの不正アクセスを許してしまう。

なぜAIはシークレットを出力してしまうのか

大規模言語モデルは、プロンプトを補完することによってテキストを生成します。ユーザーが「そのまま使える例」を求めたとき、モデルはそれを「追加の設定なしで実行できるコード」と解釈します。そのため、APIキー、パスワード、トークンなどの欠落している値を、もっともらしいプレースホルダーで埋めてしまうのです。プロンプトで明示的に言及されない限り、モデルはシークレット管理のベストプラクティスを認識していません。

VeracodeによるAI生成コードの最近の分析では、スニペットの45%にOWASP Top 10にリストされている脆弱性が少なくとも1つ含まれており、認証情報の露出が大きな割合を占めていることがわかりました。この統計は、この問題が一部の例外的なケースに限られたものではなく、これらのモデルの学習方法やプロンプトの与え方に起因する構造的な副産物であることを強調しています。

開発者が今すぐ取れる対策

最も単純な防御策は、コードファイル自体にシークレットを一切含めないことです。最も一般的で言語に依存しない方法は、環境変数を使用することです。

# token_check.py – secure version
import os
import hmac
import hashlib

SECRET_KEY = os.environ["HMAC_SECRET_KEY"]

def sign_token(data: bytes) -> str:
    return hmac.new(SECRET_KEY.encode(), data, hashlib.sha256).hexdigest()
# email_sender.py – secure version
import os
import smtplib

smtp_password = os.environ["SMTP_PASSWORD"]
server = smtplib.SMTP("smtp.example.com", 587)
server.starttls()
server.login("noreply@example.com", smtp_password)

os.environ を使用すると、実行環境から値を取得できるため、バージョン管理からシークレットを排除でき、ソースファイルを変更することなくローテーションが可能になります。同様のパターンは、コミット対象から除外された設定ファイル、シークレット管理サービス、またはコンテナオーケストレーションによるシークレット管理でも有効です。

追加の保護策

  • コードレビュー: 一般的なシークレットのパターン(例:長い英数字のシーケンス)に一致するリテラル文字列をフラグ立てする。
  • 静的解析ツール: 新しく追加されたファイル内のハードコードされた認証情報を検出するように調整されたツールを使用する。
  • プロンプトエンジニアリング: モデルに対して「すべてのシークレットに環境変数を使用してください」または「実際の認証情報は省略してください」と明示的に指示する。
  • 生成後のリンティング: コードをプロジェクトにコピーする前に、疑わしいリテラルを検索する簡単なスクリプトを実行する。

反論:これはAIコードが安全ではないことを意味するのか?

ハードコードされたシークレットが存在することは、AI生成コードが普遍的に安全ではないことを意味するわけではありません。多くの場合、モデルは開発を加速させるクリーンで構造化されたロジックを生成します。リスクが生じるのは、開発者がセキュリティ監査を行わずに、出力をそのまま本番環境で使えるものとして扱ったときです。AIは、確立されたセキュリティ慣行の代わりではなく、下書きのアシスタントとして扱ってください。

今後の注目点

  • ツールのアップデート: AIプラットフォームは、シークレットをプレースホルダーに置き換えるセーフティフィルターを組み込み始めています。これらの変化を監視することで、露出を減らすことができます。
  • ポリシーの変化: 組織はAI支援コーディングのガイドラインを正式に策定し、CIパイプラインの一部としてシークレット管理のチェックを義務付ける可能性があります。
  • コミュニティのパターン: 開発者がより多くの「安全なプロンプト」を共有するにつれて、トークン署名やメール配信などの一般的なタスクにおいて、ベストプラクティスのテンプレートがデフォルトの出力になる可能性があります。

要点: AIは数秒で動作するコードを生成できますが、開発者がシークレット管理の規律を徹底しない限り、その利便性には、システム全体を危険にさらす可能性のある認証情報の漏洩という、隠れた代償が伴います。すべてのスニペットをドラフトとして扱い、リテラルなシークレットをすべて取り除いた上で、コミットする前に環境変数や専用のVaultを介してそれらを注入するようにしてください。