解凍しただけで情報が漏れる時代に、型安全性が守るもの
Hatched by 石川篤
Aug 25, 2026
1 min read
1 views
91%
「ファイルを開かなければ安全」「機密情報を書かなければ漏れない」「型が合っていれば壊れない」。私たちは、危険な結果には危険な操作が先にあると思いがちです。しかし現実のシステムでは、もっと小さな行為が、本人の意図を越えた権限や通信を発動させます。
圧縮ファイルを解凍しただけで、Windows Explorer がSMB認証を開始し、NTLMハッシュが外部に送られる可能性がある。公開情報をいくつか組み合わせるだけで、個人の行動や所属が推測される。バックエンドでは、入力値のわずかな違いが、想定外の状態や権限の経路を生み出す。
一見すると、これは脆弱性、OSINT、プログラミング言語という別々の話です。けれども、三者の中心には同じ問いがあります。
システムは、利用者が意図していない次の行動まで、どの程度勝手に進んでしまうのか。
この問いから見ると、強い静的型付けは単なる開発者の好みではありません。それは、システムの自動的な推論と自動的な行動を制限するための、ひとつの防御設計です。
危険なのは「悪い入力」より「隠れた遷移」である
セキュリティ対策はしばしば、悪意のある入力を拒否する問題として説明されます。SQLインジェクションならクエリを無害化し、認証情報なら暗号化し、怪しい添付ファイルなら削除する。もちろん重要ですが、これだけでは不十分です。
本当に危険なのは、入力そのものではなく、入力を受け取ったシステムがどんな遷移を暗黙に実行するかです。
たとえば、利用者がアーカイブの中身を確認するために「解凍」を実行したとします。利用者の頭の中にある操作は、ファイルをローカルのディスクへ展開することです。しかしOSやExplorerの内部では、ファイルの種類を判定し、メタデータを読み込み、アイコンやプレビューを取得し、参照先を解決し、必要に応じてネットワークへ接続するかもしれません。
利用者の意図は「見る」でした。システムが実行したのは「外部リソースへ認証情報を提示する」ことでした。この差分が、攻撃者にとっての攻撃面になります。
CVE-2025-24071として知られる問題は、まさにこの差分を象徴しています。.library-msファイルを含むRARアーカイブを展開すると、展開したという事実だけでWindows ExplorerがSMB認証要求を開始し、NTLMハッシュが露出する可能性があります。ここで重要なのは、被害者が悪意あるプログラムを実行したわけではない点です。スクリプトを許可したわけでも、認証情報を入力したわけでもありません。単純なファイル操作が、予想外のネットワーク動作へ接続されていました。
この構造は、ソフトウェアの「便利さ」の裏側にあります。自動プレビュー、自動同期、自動補完、自動認証、リンクの自動解決。これらは一つひとつ見ると親切な機能ですが、組み合わさると、利用者の操作を越えてシステムが行動する自動化された権限の連鎖になります。
安全性を考えるとき、私たちは「この入力は危険か」と問うだけでは足りません。次の三つを分けて考える必要があります。
- 入力面: 何をシステムに渡したか
- 推論面: システムがその入力から何を意味すると判断したか
- 行動面: その判断によって何を自動実行したか
攻撃は、入力面を直接破壊するとは限りません。むしろ、推論面と行動面の境界を利用します。普通のファイルを、ネットワーク資源を参照するオブジェクトとして解釈させる。単なる文字列を、命令やパスとして扱わせる。単なる公開情報を、個人の生活パターンとして再構成する。危険は、データが意味へ変換される瞬間に発生します。
OSINTが示す「情報は単体ではなく、接続で強くなる」原理
公開情報は、単体では無害に見えることが多いものです。ユーザー名、投稿時間、職歴、写真の背景、イベント参加、使用しているサービス。どれも単独では決定的な情報ではないかもしれません。
しかし、複数の情報を時系列や地理、組織、技術的特徴で結びつけると、別の像が現れます。あるアカウントの投稿時間から生活圏が推測され、写真の看板から場所が絞られ、職歴とイベント参加から所属組織が推測される。情報は増えただけではありません。関係性によって、情報の意味が変わったのです。
これはファイルの脆弱性と同型の構造を持っています。ファイルの中の一つの属性だけを見れば無害でも、その属性がExplorerの処理、SMBの認証、外部サーバーとの接続と結びつくと、予想外の結果になります。OSINTでは、人間の行動と公開情報が接続されます。脆弱性では、データと自動処理が接続されます。
どちらも、危険の大きさは部品の危険度の合計では決まりません。部品同士がどんな遷移を作るかで決まります。
この視点を「接続密度」と呼んでみましょう。接続密度が高いシステムでは、ひとつの情報が複数の推論や処理を呼び起こします。便利である一方、利用者は結果を予測しにくくなります。表示するだけで通信する。名前を入力するだけで権限が推定される。型の違う値を同じIDとして扱う。こうした仕組みでは、事故は異常操作からではなく、日常操作から生まれます。
OSINTの実務が教えるのは、監視の技術だけではありません。それは、人間や組織が残す小さな痕跡は、別の文脈に置かれると新しい権限を持つという事実です。プログラムも同じです。文字列、ファイル、識別子、日時、URLは、単なるデータとして存在するのではなく、文脈によって命令、資格、経路、証拠へ変わります。
だからセキュリティは、秘密を隠すだけの問題ではありません。自分のデータが、どの文脈で別の意味に変換されるかを管理する問題です。
強い型付けは「正しい値」を作るより「誤った遷移」を消す
バックエンド開発でGo、Rust、Scalaのような強い静的型付けを支持する理由は、単にコンパイル時にミスを見つけられるからではありません。より本質的には、システムが取り得る状態と遷移を、コードの構造で狭められるからです。
たとえば、すべてを文字列で表す設計を考えてみます。ユーザーID、メールアドレス、管理者ID、ファイルパス、URL、認証トークンが、すべてstringです。コンパイラから見ると、どれも同じ型です。そのため、関数に渡す値を取り違えても、構文上は問題になりません。
一方で、UserID、AdminID、FilePath、ExternalURLを別の型として扱えば、似た値の混同を構造的に減らせます。文字列の中身を検査するだけではなく、その値が何として存在するのかを型に刻み込むのです。
これは、入力検証とは異なる防御です。入力検証は「この文字列の形式は正しいか」を問います。強い型付けは「この値を、この場所で、この操作に使ってよいか」を問います。形式が正しい攻撃文字列は存在しますが、正しい型を持たない値は、そもそも危険な関数へ到達できないように設計できます。
より具体的に考えてみましょう。外部から受け取ったURLを、画像の取得先としてだけ使うつもりだったとします。ところが、そのURLが内部ネットワークのアドレスや認証を誘発する特殊な参照先になる可能性がある。単にURL型を作るだけでは十分ではありません。
次のように、意味の段階を分ける必要があります。
- 外部入力として受け取った未検証の文字列
- 構文的にURLとして解釈できる値
- 許可されたスキームとホストを持つURL
- サーバーから取得してよい外部リソース
この四つを同じ型や同じ変数で扱うと、検証前の値が検証済みの値として流れてしまいます。反対に、型を段階ごとに分ければ、検証という境界をコードの中に残せます。
Rustの所有権やenum、Goの明示的なエラー処理、Scalaの代数的データ型は、それぞれ表現は異なりますが、共通した方向性を持ちます。曖昧な状態を暗黙に許さず、可能な状態を明示し、失敗を通常の制御フローとして扱うことです。
ここで、型システムを「データの品質管理」とだけ考えるのは狭すぎます。型システムは、システムの自動推論に許可される範囲を設計する仕組みです。
型安全性とは、間違った値を見つける技術ではない。間違った値が、間違った意味へ変換される経路を最初から作らない技術である。
この考え方をファイル処理にも適用できます。展開されたファイルを、単なるローカルデータとして扱うのか、外部参照を含むオブジェクトとして扱うのか。プログラムはその区別を明示すべきです。プレビュー可能なデータと、外部通信を誘発し得るデータを同じ安全レベルに置かない。表示操作と実行操作を同じAPIに隠さない。型や権限モデルによって、両者の距離を広げるのです。
セキュリティ設計の新しい単位は「機能」ではなく「意図との差分」
ソフトウェアの仕様書は通常、「ユーザーが何をできるか」で書かれます。ファイルをアップロードできる。画像をプレビューできる。URLを登録できる。管理者を招待できる。
しかし攻撃面を発見するには、もう一つの記述が必要です。
ユーザーが意図した結果と、システムが実際に行う全処理の差分は何か。
この差分を、意図乖離と呼びます。意図乖離が大きいほど、利用者は安全性を判断できません。UI上は「解凍」「表示」「保存」と書かれていても、内部では認証、名前解決、外部通信、権限継承、コード解析が走っているかもしれません。
開発チームが行うべきなのは、機能一覧のレビューだけではありません。各操作について、次の表を作ることです。
| 利用者の操作 | システムの暗黙処理 | 外部に起きる可能性 | 必要な境界 |
|---|---|---|---|
| ファイルを展開する | メタデータ解析、参照解決 | 外部認証や通信 | サンドボックス、ネットワーク遮断 |
| URLを登録する | 名前解決、取得、リダイレクト | 内部資源へのアクセス | 宛先制限、再検証 |
| IDを入力する | 権限照合、データ取得 | 他人の情報の参照 | 型付きID、認可の再確認 |
| 画像を表示する | プレビュー生成、形式判定 | パーサー脆弱性の利用 | 変換隔離、最小権限 |
この表の目的は、すべての自動化を禁止することではありません。自動化には大きな価値があります。問題は、自動化が権限を持つのに、その権限が利用者から見えないことです。
そこで、実務では「自動化の予算」を設けるとよいでしょう。読み取りだけの操作には、ネットワークアクセスを与えない。プレビューには、認証情報を継承させない。外部から来たデータは、内部データと同じ解釈器や権限で処理しない。危険な副作用を起こす処理には、明示的な同意や別のAPIを要求する。
これは最小権限の原則を、ユーザー権限だけでなく処理の権限へ拡張したものです。サービスが管理者として動いているかどうかだけでなく、パーサーがネットワークへ出られるか、プレビュー機能が認証情報へ触れられるか、文字列処理が命令の文脈へ入れるかを管理します。
開発者と利用者が明日から変えられること
この統合的な見方は、理論だけではありません。日常の設計、レビュー、運用に落とし込めます。
1. 操作ではなく、発生する副作用を列挙する
「ファイルを開く」「画像を表示する」と書いたら、それで終わりにしないでください。DNS問い合わせ、SMBやHTTP通信、認証情報の送信、テンポラリファイルの生成、コード解析、権限継承まで洗い出します。利用者の操作から一段ずつ先へ進み、どの時点で外部世界に触れるかを記録します。
2. 未検証、検証済み、許可済みを別の型にする
文字列を受け取ったら、すぐに信頼できる値として扱わないことです。RawInput、ParsedURL、AllowedExternalURLのように、検証段階を型や構造体で分けます。型名が長くなっても、境界が見えるほうが安全です。
3. 「表示」と「実行」を分離する
プレビュー処理が外部リソースを取得したり、メタデータを解釈して認証を開始したりしないようにします。表示のための処理には、ネットワークを遮断した環境、読み取り専用の権限、限定されたパーサーを使います。
4. OSINTの発想でログを見直す
ログを一件ずつ確認するだけでなく、複数のイベントを組み合わせたとき何が推測できるかを考えます。時刻、IP、ユーザーエージェント、ファイル名、エラー内容が結びつくと、個人や組織の行動が見えてしまうことがあります。ログは防御に役立つ一方で、別の攻撃対象にもなります。
5. レビューで「この値は何を意味するか」と問う
変数の型だけでなく、その値がどの文脈で権限を持つかを確認します。IDは単なる文字列ではない。URLは単なる文字列ではない。ファイル名は単なる文字列ではない。意味を持つデータには、意味に応じた境界と寿命を与えます。
Key Takeaways
- 入力の危険度ではなく、入力が引き起こす隠れた遷移を調べる。 解凍、表示、保存のような無害に見える操作にも、通信や認証が含まれていないか確認する。
- データを、意味の段階ごとに別の型へ分ける。 未検証の入力、構文解析済みの値、許可済みの値を同じ変数で扱わない。
- 自動化に処理権限を与えすぎない。 プレビューや解析のコンポーネントから、ネットワーク、認証情報、内部資源へのアクセスを切り離す。
- 情報の組み合わせによる推測可能性を評価する。 それぞれは無害なログや公開情報でも、接続すると個人、場所、権限が推測できる場合がある。
- セキュリティレビューでは意図乖離を探す。 利用者が期待する結果と、システムが実際に実行する処理の差分を明文化する。
私たちは長いあいだ、セキュリティを「悪意ある人を止めること」と捉えてきました。しかし現代のシステムで起きる多くの問題は、悪意のある入力と善意の操作の間にあります。利用者は普通にクリックし、開発者は便利な自動処理を実装し、サービスは正しい形式のデータを受け取る。それでも、複数の小さな解釈が連鎖して、誰も明示的に選んでいない行動が実行されます。
強い型付け、サンドボックス、最小権限、OSINT的な関連付けの分析は、別々の専門知識に見えます。けれども、すべてが守ろうとしているものは同じです。それは、意味が勝手に変わり、権限が勝手に増え、行動が勝手に連鎖することを防ぐことです。
安全なシステムとは、何も自動化しないシステムではありません。利用者の意図を越える処理を自動化するとき、その境界を明示し、狭くし、検証可能にするシステムです。
次にファイルを解凍するとき、URLを受け取るAPIを書くとき、ログを設計するとき、こう問いかけてください。
この操作の次に、私が頼んでいない何が起きる可能性があるか。
その問いをコードの型、実行環境の権限、ログの設計、ユーザーインターフェースにまで埋め込めたとき、セキュリティは後から貼る警告ではなくなります。それは、システムが勝手に意味を作り、勝手に行動する範囲を設計する、構造そのものになります。
Sources
Hatch New Ideas with Glasp AI 🐣
Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)
Start Hatching 🐣