Python勉強会

セキュリティを考える

1. はじめに

Anthropic のソースコード流出や、Axios に対するサプライチェーン攻撃など、セキュリティが話題になる今日この頃。一度、Python を題材にキー・入力・依存関係の観点で掘り下げます。

次のスライドでは、生成AIがコードを書いてくれること自体のリスクと、実行環境ごとのイメージを共有します。

Samurai

2. 生成AIが書くコードをどう扱うか

生成AIはコードを素早く出してくれますが、正しさや安全性は保証されません。「どこで動かすか」「何を信じるか」を意識しましょう。

実行環境によって、想定されるリスクは変わる

ローカルでのみ実行 — 影響は主に自分のマシンに閉じる。ただしゼロではない

閉域ネットワーク上で実行 — 社内・限定環境。漏洩や横展開の範囲が広がる

Web 上にデプロイ — 不特定多数・常時接続。攻撃面・影響が大きくなりやすい

下に行くほど、想定外の損害が大きくなりやすい、というイメージです。

ローカルでも気をつけること(例)

  • API キーや機密をコードに直書きしない(誤コミット・漏えい)
  • コピペしたコードの eval やシェル実行を鵜呑みにしない
  • pip install するパッケージの名前・出所を軽く意識する
Character

3. 今日やること

この心構えを踏まえ、今日は次のトピックを扱います。

アジェンダ

  • API キーを安全に使う(プロジェクト単位・環境変数・ローテーション)
  • ハンズオン①:環境変数から OpenAI API を呼ぶ
  • 入力とプロンプトインジェクションのイメージ
  • ハンズオン②:eval の危険さを体感する(デモ用)
  • requirements.txt などで依存を書き出す意味・重要性
  • pip と Snyk、バージョン固定とサプライチェーン(Takumi Guard の一例)

📡 オンライン接続の確認

画面は見えていますか?
音声は聞こえていますか?

問題がある場合は、Slackのチャットでお知らせください。

Ninja

4. APIキーを安全に使う

キーは漏れる前提で制限・監視の設計を考えます。コードに直書きせず、環境変数や .env.gitignore に含める)、CI では GitHub Secrets などで渡します。

運用のポイント
  • プロジェクト(用途)ごとにキーを作る — 影響範囲を分け、失効・ローテーションしやすくする
  • コードに書かない — 環境変数から読む(例:os.environ["API_KEY"]
  • .env.gitignore、リポジトリには載せない
  • GitHub Actions などでは Secrets に登録して参照
  • 漏れたらローテーション(無効化 → 新キー発行)の手順を決めておく
やってはいけないこと
  • API キーを Git にプッシュする
  • スクリーンショットやチャットでキーをそのまま共有する

プロバイダ側でキーに最小権限(使う API だけ)を付けられる場合は、それに合わせましょう。

Character

5. ハンズオン① — 環境変数から OpenAI を呼ぶ

事前に pip install openai を実行し、環境変数 API_KEY を設定してから動かします。

import os import openai from openai import OpenAI # APIキー利用の注意点 # 漏れる前提で制御する(制限・監視) # コードに書かない=環境変数に入れる。 # 最小権限にする(このコードなら、Responses=WriteのみでOK。) OPENAI_API_KEY = os.environ["API_KEY"] client = OpenAI(api_key=OPENAI_API_KEY) input_text = input("質問を入れてね:") response = client.responses.create( model="gpt-5.4-mini", input=input_text ) print(response.output_text)
Ninja

6. 入力フォームは攻撃される前提

Web のフォームや input() で受け取った文字列は、信頼しないのが基本です。LLM アプリでは、ユーザー入力がシステム側の指示をねじる攻撃をプロンプトインジェクションと呼びます。

イメージ
  • 「前の指示は忘れて…」のように、モデルの振る舞いを意図的に変えさせる
  • 機密を吐かせる・別のツールを悪用する、などにつながりうる

対策は一発ではありませんが、入力の検証・役割の分離・テンプレート化など、設計として意識することが第一歩です。

Ninja

7. ハンズオン② — eval の危険さ(デモ)

ユーザー入力を eval に渡すと、任意の Python 式が実行されます。実運用では使いません。ローカルで挙動だけ確認する想定です。

input_text = input("質問を入れてね:") eval(input_text) # 例として eval に渡すと危険が分かる入力のイメージ: # [print(i) for i in range(1,11)] # print(os.environ)
なぜ危ないか
  • eval は式評価であり、悪意のある入力で処理系そのものが乗っ取られる
  • 環境変数の読み取りなども、入力次第で可能になりうる
Samurai

8. requirements で依存を管理する意味

手元で pip install パッケージ するだけでは、「いつ・誰が・どのバージョンを入れたか」がプロジェクトに残りません。requirements.txt(や poetry.lock / uv.lock など)に依存関係を書き出して共有することで、チームと CI・本番が同じ前提を持てます。

なぜ重要か
  • 再現性 — 環境ごとにバージョンがバラつかず、「自分の手元では動いた」の調査がしやすい
  • 見える化 — プロジェクトがどの外部コードに依存しているかが一覧になる
  • セキュリティ対応 — CVE のニュースが出たとき「自分たちは影響あるか」を判断しやすい。スキャナや監査の前提にもなる

次のスライド以降は、この「一覧」をどう保護・点検するか(Snyk、バージョン固定、プロキシなど)につながります。

Character

9. pip のライブラリと Snyk

PyPI のパッケージにも脆弱性はあります。リポジトリと Snyk を連携しておくと、無料枠でも深刻度の把握や修正 PR まで進めやすくなります。

Snyk
Ninja

10. バージョン固定とサプライチェーン

先ほどのように依存をファイルに書いたうえで、バージョンを固定(ピン留め)すると、意図しない更新や「いつの間にか変わった挙動」を抑えられます。新しく出たパッケージは少し様子を見る、という姿勢も有効です。

Takumi Guard(一例)
Ninja

11. まとめ & 次の一歩

今日は生成AIのコードの扱いと実行環境のイメージを共有したうえで、APIキー(プロジェクト単位・環境変数・ローテーション)→ 入力とプロンプトインジェクション → eval の危険性 → 依存の明示(requirements)→ Snyk とバージョン固定・サプライチェーンを扱いました。

  • キーはコードに書かず、漏れたら止めて作り直す前提で運用する
  • ユーザー入力は信頼しない(LLM ではプロンプトインジェクションも意識する)
  • eval のような「全部実行」系は実装に使わない
  • 依存は requirements などで明示し、固定・スキャン・新規パッケージは慎重に
  • デプロイほど影響が大きくなりやすいが、ローカルでもキー・コピペ・依存に注意する

質問や「うちのプロジェクトだとこうかも」があれば、時間の範囲で共有しましょう。

HAGAKURE Logo
1 / 12