-
Enhanced Securityによるアプリの保護
XcodeのEnhanced Securityが提供するパワフルなツールを活用し、メモリ安全性の脆弱性からアプリを保護する方法を学びましょう。このセッションでは、攻撃対象領域の削減、ハードウェアによる緩和策、Enhanced Security Extensionsによる封じ込めなど、Appleがプラットフォーム全体に適用する防御戦略についてご紹介します。Xcodeプロジェクトでこれらの機能を有効にし、効果的なセキュリティエンジニアリング戦略を確立する方法をご確認ください。
このセッションは、「Appleに相談」のイベントである「アプリの強化:セキュリティを向上させるための必須戦略」の一部として実施されました。詳しい情報や関連セッションについては、ビデオ全編をご視聴ください。リソース
-
このビデオを検索
おはようございます AppleのMark Mitchellです セキュリティエンジニアリングチーム所属で 同僚のDevinも一緒です 本日は メモリ安全性の脆弱性から アプリを保護する フレームワークについて説明します
本日Devinと私がお話しする各種戦略を 慎重に組み合わせることこそが iPhoneが最も安全な コンシューマー向けデバイスとしての 評価を得てきた理由です
本日のセッションでは 各機能の概要と目的を解説し AppleがアプリやOS お客様を守るために これらをどのように活用しているかの 実例をご紹介します
Xcodeを使えば Appleが採用している 高度なテクノロジーを活用して アプリのユーザーを保護できます
アプリは生活のあらゆる部分に関わっています 誰もが個人情報 位置情報 閲覧履歴 写真 メッセージ 財務情報などを 安心して預けられる 欠かせないツールです 同時に アプリとユーザーは インターネットに接続されているため 脆弱性があると ユーザーが 攻撃に晒されるリスクが生じます 攻撃による被害は 詐欺や個人情報の窃盗から 恐喝 さらには稀なケースとして 現実世界での身体的脅威にまで 及ぶことがあります
人々はデータがプライベートかつ 安全に保護されることを期待しており その約束が破られれば 信頼の失墜につながります セキュリティは プライバシーを実現する 技術的な基盤です
まず メモリの安全性とは何か そしてそれが引き起こす さまざまな脆弱性の概要から始めます
次に アプリ保護に活用できる セキュリティエンジニアリング戦略の 概要と 自社アプリでの 活用成果について説明します そして最後に Devinが Enhanced Securityケーパビリティを 備えたXcodeを使い これらの戦略を実践する方法を紹介します
では メモリ安全性とは何を意味するのでしょうか
メモリ安全性のバグは 最も一般的な脆弱性カテゴリの1つで 攻撃者はメモリ破壊を利用して プログラムの動作を変更または 不正操作します
Appleのセキュリティエンジニアは メモリ安全性を「意図された動作」と 「意図しない動作」の観点から捉えています
通常の使用では プログラムは デベロッパの意図通りに動作し 妥当な処理のみを実行します 実行フローは迷路のようなものと 考えることができます 迷路の正しいルートは デベロッパが 特定の処理のために意図したコードであり 他のルートは使用されない または到達不能なコードパスです
到達不能なパスとは 例えば カメラ起動やメール送信を行う 未使用フレームワーク内の コードなどが該当します
攻撃者はメモリ安全性の脆弱性を悪用して プログラムを予期しない状態に陥らせ デベロッパの意図とは 全く異なる動作を実行させようとします この例では 意図したパスの途中に
脆弱性があることで 迷路の新たな抜け道ができたり 意図しないコードを実行する 新たなパスが作られてしまいます それにより アプリにカメラを強制起動させたり メールを送信させたりする コードが呼び出される可能性があるのです
メモリ安全性はセキュリティの根幹であり これがなければ 上位のセキュリティ特性を保証できません 例えば パスワードのハッシュ化方式が どれほど強固であっても 攻撃者が脆弱性を突いて システムへのアクセス権を 取得できてしまえば意味がありません
具体例を見てみましょう シンプルなログイン関数です ユーザー入力のパスワードを取得し テストを素早く行うために デバッグビルドなら認証をスキップします そしてパスワードをハードコードされた シークレットと比較する関数を呼び出し ログイン結果を返します
お気づきかもしれませんが 大きな赤いバツ印があります 明らかに脆弱性があるコードであり 決して真似してはいけません ここでは パスワードのコピー用に スタック上に32文字分の領域を 割り当てていますが コピーAPIは領域サイズを認識していません そのため テキストフィールドの全文字を バッファに書き込んでしまい スタックバッファオーバーフローが 発生します
メモリ内部では 大まかに このようなことが起きています ローカルのパスワード格納領域の直後に デバッグログインフラグを保持する メモリが配置されています
パスワードが例えば18文字であれば 安全に収まります
しかし 攻撃者が32文字を超える 文字列を送信したらどうなるでしょうか
メモリ安全ではない言語で書かれているため 隣接するメモリ領域を上書きし始めます ここではデバッグログインフラグの領域です その結果 デベロッパの意図に関わらず
プログラムがif文に到達した際 値が攻撃者により上書きされていれば 認証をスキップして強制的に trueを返せてしまいます しかし実際には このコードにはさらに 深刻な問題が存在します
未認証ログインだけでなく デバッグログインフラグに続くメモリには 比較処理のためにプログラムが呼び出す 関数ポインタのアドレスが配置されています
攻撃者がさらに長いパスワードを送り込むと パスワードバッファからフラグを越えて溢れ 関数ポインタを任意の値に書き換えられます つまり 比較関数を呼び出そうとすると 実際には攻撃者が指定した 任意の関数が呼び出されることになります 攻撃者はプロセスを完全に掌握し 他のコードパスにアクセスして ユーザーデータを窃取することが可能になります
この例はバッファオーバーフローであり メモリ安全性の特性の1つへの違反です メモリ安全性には5つの軸があります 境界安全性(Bounds Safety)は すべてのメモリアクセスが 割り当て領域の境界内で行われることを保証します
ライフタイム安全性(Lifetime Safety)は メモリが有効な間のみ使用され 他の用途に再利用されていないことを保証します
型安全性(Type Safety)は 意図しない型を通じて誤って メモリにアクセスすることを防ぎます
初期化の保証は メモリ使用前の 確実な初期化を保証します
そしてスレッド安全性(Thread Safety)は 異なるスレッド間のメモリ破壊を防ぎます
攻撃の全体像は一般的に次のようになります 攻撃者は アプリのデータを 侵害するだけでなく それを足がかりとして 他のシステムコンポーネントを攻撃し プラットフォーム保護を崩すために カーネル権限への昇格を狙います ファイルだけでなく 位置情報 写真 連絡先 マイクなどのアセットを狙うからです
このように アプリはより大規模な 攻撃への玄関口となることがよくあります
同時に 現代のアプリは多機能であり 通常使用時でも多くのアセットへの
アクセス権が付与されています OSのセキュリティが強化されるにつれ 将来的には攻撃者が アプリからデータを収集するだけで満足し OS全体を狙わないケースも想定されます だからこそ 私たちが足並みを揃えて セキュリティ対策を進めることが不可欠です
それでは メッセージ Safari メールなどの アプリやサービスを保護するために Appleで採用されている戦略をご紹介します
十分に複雑なコードベースには 常に脆弱性が存在し得るというのが 一般的な認識です
そのためAppleでは 互いに補完し合う 多層構造のセキュリティに依拠しています
本日紹介する多くの技術については 後ほど掘り下げますが ここでは基本概念と Appleの適用アプローチ 効果の評価方法 およびアプリへ 導入するための労力について説明します
5つの戦略についてお話しします
1つ目は Swiftのような言語を使い メモリ安全性脆弱性を排除する方法
2つ目は アタックサーフェスを縮小し 脆弱性に到達できなくする方法
3つ目は 緩和策により脆弱性の悪用を防ぐ方法
4つ目は 万が一攻撃が起きた場合の 被害を封じ込める方法 そして最後に コードから脆弱性を 検出・排除するためのテクニックです
最も包括的な防御アプローチは そもそも脆弱性の混入が起こりにくい 言語を使用することです
AppleはSwiftに注力しており Swiftは標準でメモリ安全性を備えています Swiftは皆様のアプリだけでなく OSや WebKit 複雑なパーサー さらにはSecure Enclaveの ファームウェアのような重要領域でも 採用が進んでいます
もちろん 多くのアプリには C言語系の既存コードベースがあり それらはメモリ安全ではありません Enhanced Securityでは C言語向け
-fbounds-safetyやアノテーション C++標準ライブラリのハードニングなど 境界エラーを低減するツールを提供しています しかし これらは完全なメモリ安全性への 通過点と考えてください 他の4つの軸に対応していないため 最終目標ではありません
5つの軸でC系言語とSwiftを比較すると C系言語にはこれらの保護が一切ありません Swiftは境界チェック付き配列や 標準ライブラリにより境界安全性を実現し ARCと所有権でライフタイム安全性を確保します 実行時のキャストチェックにより型安全性を保証し 使用前の初期化を必須として初期化を保証し Swift Concurrencyにより
データ競合を防いでスレッド安全性を提供します
以上がメモリ安全性脆弱性を排除する概要です 詳しくは 後ほど開催の「Writing Security Sensitive code in Swift」をご覧ください
Appleが多用する2つ目の戦略は アタックサーフェスの縮小です
自社コードや依存フレームワーク内の 全脆弱性を把握することは不可能です しかし 攻撃者がアクセス可能なコード量を 必要な最小限に制限することは可能です これにより 実行コードに脆弱性が 存在する確率を大幅に低減できます
Appleはシステム全体でこの手法を用い 攻撃者の活動領域を狭めています パース可能な複雑なドキュメント形式の制限から 信頼性に基づく条件付き機能の提供 さらにはロックダウンモードによる 機能全体の無効化まで多岐にわたります
フォーマット制限の例を挙げると アプリがJPEGのみを送受信する場合 他の形式の処理を許可してしまうと 不要な数百万行ものパースコードを 攻撃者に晒すことになります
この場合の最善策は 正しい形式の JPEGであるかを検証するか Core GraphicsがJPEGのみをパースするよう設定し 不正なトラフィックは破棄することです
もう1つ アタックサーフェスを晒しやすいのが アプリ内ブラウジングや広告SDKなどの WebViewを通じてWebコンテンツを レンダリングするケースです
iOS 26.4以降 WebKitには 「Enhanced Security WebViews」という 2つの強力な新オプションが導入されました これにより セキュリティを強化しながら Webコンテンツの処理方法を制御できます
デフォルトのWebViewは Safariの セキュリティ緩和策を提供しつつ WebKitのパワーとパフォーマンスを アプリ内でそのまま発揮します
第1のモード「制限モード:互換性の最大化」は 完全なWeb互換性を維持しつつ 複雑なコードの大部分を排除し 最新のハードウェアセキュリティ 緩和策の適用を高めます
第2のモード「制限モード:ロックダウン」は アプリのWebViewをロックダウンモードと 同等の強固な保護に設定し 使用頻度の低いWeb技術を排除します
Appleでは iOS 26.4のメール Quick Look ショートカット Apple Adsなどで Enhanced Security WebViewsの採用を 進めています ぜひお試しください
アタックサーフェス縮小は効果的ですが 安全でない言語のコードが残る限り 脆弱性は存在するという前提に 立つ必要があります
その場合 次に効果的な防御策は 攻撃者の悪用能力を削ぐことです
私たちは「セキュリティ緩和策」と 呼ばれるテクノロジー群を用いてこれを行います
緩和策という概念自体は新しくなく 過去30〜40年にわたり進化してきました Appleは常に新しい緩和策を開発・提供しており 安全なものはデフォルトで有効化されています
緩和策は Clangスタックプロテクタや ASLRといった初期の防御から カーネル整合性保護(KIP)などの 最新ハードウェア支援技術にまで及びます
Xcode 26には アプリ保護のための 強力な新しいソフトウェアおよび ハードウェア支援型緩和策が用意されています
ポインタ認証(Pointer Authentication)は コンパイラと連携するハードウェア技術です 脆弱性の悪用を検知・防止し 万が一の際も制御フローの完全性を維持します
iPhone 17シリーズで導入された メモリ整合性強制は 5年間の研究・設計の集大成であり セキュアアロケータ 拡張メモリタギング タグ機密性強制(TCE)の上に 構築されています
詳細は 後ほどのセッションおよび security.apple.comのブログをご覧ください
Appleは メモリ整合性強制が コンシューマーOS史上最も重大な メモリ安全性の刷新であると確信しています
しかし稀に 高度な攻撃者が 緩和策を突破して悪用する場合があります
そのような場合の最後の防衛線が 「封じ込め(Containment)」です
先ほどの攻撃チェーンを振り返ってみましょう 攻撃者がアプリの脆弱性を突いて プロセスを完全に乗っ取ったとします
理想は 攻撃者を隔離環境に閉じ込め アプリデータやプラットフォームに アクセスさせないことです
iPhone初期から アプリはサンドボックス内で 実行され 不正アクセスを防いできました
しかし 高度な攻撃者に対しては さらに極端な隔離が必要です
とはいえ アプリ全体を完全に遮断することは 不可能です UI描画などの権限が必要だからです
そのため メッセージやSafariでは データ処理を厳重なサンドボックス環境に移す マルチプロセスアーキテクチャを設計しました
これにより 万が一侵害されても メッセージやCookieなどの データが存在しない環境に閉じ込め 権限昇格を防ぐことができます
Xcode 26では「Enhanced Security Extensions」を通じてこの環境を利用できます
メッセージが写真を受信した際の 仕組みを説明します
メッセージは「BlastDoor」拡張を呼び出します ポリシーは「受信アセットは 無害化されるまですべて悪意あるものとみなす」です
高権限のメッセージアプリは BlastDoorから返る単純な型を検証するだけで済み 危険なパース処理は最低権限で実行されます
メッセージが届くと アプリはパースを行わずに BlastDoorプロセスへ直接送信します
BlastDoor内でパースが開始され 有効な場合は 表示用のシンプルな形式に変換されます
画像が無効な場合は処理を破棄します 脆弱性を突かれても データベースへのアクセス権を持たない 第2プロセス内に封じ込められます
BlastDoorからデータを返す際 プロセス自体が侵害されている可能性を想定し 返されるデータは信用しません
そのため メッセージ側でデータが 正しい画像であるかを安全に検証します Swiftとアタックサーフェス縮小を 組み合わせて検証し 完了後に画面へ表示します
これが Appleが機密性の高い領域で 封じ込めを活用している一例です
最後の戦略は 他と並行してコード内の 脆弱性を可能な限り検出し排除することです
これ単体では不十分ですが 攻撃者が狙う脆弱な箇所を特定するのに効果的です
Appleでは 手動と自動の手法を組み合わせています コード監査を実施し レビュー支援やCIで Clang Static Analyzerを活用しています
また 多数の入力を自動生成する ファジングを活用し Address SanitizerやThread Sanitizerで 積極的に脆弱性を検出しています
以上がメモリ安全なコードに向けた Appleの多層アプローチです Swiftによるバグ排除 アタックサーフェス縮小 緩和策の適用 Enhanced Security Extensionsによる封じ込め バグ検出を組み合わせて実践してください
それでは Devinに交代します セキュリティ言語・ツール開発を統括しています ありがとうございました
Mark ありがとう Devin Coughlinです Developer Security Toolsグループを率いています
Xcodeは最先端のセキュリティをもたらす 厳選された保護機能を提供します
各保護機能の詳細 有効化の方法 最大の保護を得る組み合わせ方を説明します
セキュリティとは トレードオフの見極めです メモリ安全性において最も重要なのは セキュリティ上のメリットと エンジニアリングコストのバランスです
縦軸をメリット 横軸を導入の容易さとした グラフで考えてみてください
容易でも効果が小さい保護もあれば 難易度は高くても強固な保護もあります
目指すべきは 最小限の労力で最大の効果を得る 右上隅の「スイートスポット」です
Appleの目標は ハードウェア OS 言語を 緊密に協調設計し 高性能を維持しつつ理想的な保護を提供することです
例えば メモリ整合性強制は 低い導入コストと高パフォーマンスを両立します
ここでは4つの保護カテゴリを説明します
出荷前にバグを見つける「バグ検出ツール」
アプリ全体の防御を底上げする「アプリ全体の保護」
C/C++に境界安全性を追加する「コードのハードニング」
そして完全なメモリ安全性を提供する「Swift」です
Markは新規コードベースについて 高い保護から低い保護へと順に説明しました 新規開発はそこから始めるべきです 最初からアプリ全体を 最高レベルで保護するのが理想的です
しかし 既存アプリに適用する場合は 即効性のある保護と時間のかかる保護を 戦略的に選定する必要があります
そこで 導入が容易な保護から順に説明します
まずはバグ検出ツールです
これらはビルド時やデバッグ時に バグを見つけるためのツールです
右下の象限に位置し 実行して問題を 修正するだけで簡単に使えます
全バグを見つけられるわけではありませんが 強固な保護を導入するための第一歩となります
最初にご紹介するのはSanitizer(サニタイザ)です
計測コードを含めて再コンパイルし 実行時にバグを検出します 誤検知は極めて僅かです
Address Sanitizerは 有効メモリを追跡し バッファオーバーフローや解放後使用を検出します
Markが先ほど示したような バッファオーバーフローや ダングリングポインタによる 解放後使用バグの検出に非常に優れています
ヒープ スタック グローバル変数の メモリ破壊を発見し バックトレースを表示します
Thread Sanitizerは スレッド間のデータ競合を検出します
次はClang Static Analyzerです
実行することなく 実行パスをシミュレートして バグを検出します C C++ Obj-Cに対応します
バッファオーバーフロー 解放後使用 未初期化メモリ使用 危険なAPI使用を検出します
ビルド設定で有効にし Productメニューから 「Analyze」を選択して実行します
バグが見つかると 顕在化する制御フローの経路が表示されます
Address Sanitizer Thread Sanitizer Clang Static Analyzerを活用して ビルド時やテスト時にバグを洗い出しましょう
次に「アプリ全体の保護」について説明します コードやフレームワークを含む アプリ全体のセキュリティ基準を引き上げます
型付きアロケータ ハードウェアメモリタギング ポインタ認証 読み取り専用メモリ 拡張機能の5つです
1つ目は「型付きアロケータ」です 解放後使用攻撃から保護する新アロケータです
高い保護性能を持ちながら導入が非常に容易で スイートスポット付近に位置します
解放後使用では 解放領域に別の型を割り当てさせ 型混乱(Type Confusion)を引き起こします
型付きアロケータは 異なる型を異なる メモリバケットに割り当てて型混乱を防ぎます
有効化するには Signing & Capabilitiesで Enhanced Securityを追加し 設定を有効にするだけです
2つ目は「ハードウェアメモリタギング」です ヒープメモリのオーバーフローや解放後使用を防ぎます
iPhone 17 M5搭載Mac Vision Proで利用可能です
ポインタとメモリ割り当てにタグを付与し CPUがタグの一致を検証して安全にトラップします
タグ不一致はアプリをクラッシュさせるため サニタイザや診断機能で十分にテストし メモリ破壊を修正してから有効化してください
詳細は「Secure your App with Memory Integrity Enforcement」をご覧ください
3つ目は「ポインタ認証」です
ハードウェアとOSが連携し 制御フローの完全性を保護します
iPhone XS以降および全Appleシリコン搭載Macで 利用可能です
Markが先ほど説明した スタックバッファオーバーフローを思い出してください
CPUがポインタに暗号署名を付与・検証し 不正な関数呼び出しを防ぎます
利用にはarm64とarm64eを含む ユニバーサルバイナリのビルドが必要です
4つ目は「読み取り専用プラットフォームメモリ」です
dyldのメタデータを攻撃者の改ざんから保護します メタデータ変更にはシステムAPIを使用してください
5つ目は「Enhanced Security Extensions」です
Markが説明したように このアプローチは封じ込めの一形態です 信頼できないデータ処理を別プロセスに分離し 侵害時の被害を防ぎます
Enhanced Securityケーパビリティを採用し 拡張機能を作成してください
続いて「C/C++のコードハードニング」です
「C++標準ライブラリのハードニング」は std::spanやvectorの境界外アクセスを防ぎます
さらに「Bound-safe buffer usage in C++」により 生のポインタ演算を禁止し 安全な抽象化を強制します
C言語向けには「-fbounds-safety」により アノテーションと実行時チェックで境界安全性を実現します
そして 完全なメモリ安全性を実現するのが「Swift」です
Swift 6.2では 低レベル処理向けの新しい型 「Span」が提供され 連続メモリへ安全にアクセスできます
Spanはゼロオーバーヘッドとメモリ安全性を両立します
新規コードはすべてSwiftで記述し 重要な既存コードは積極的にSwiftで書き直してください
XcodeでEnhanced Securityを有効にし 拡張機能で信頼できない入力を隔離し
C/C++をBounds Safetyで保護し 重要箇所の刷新にはSwiftを採用しましょう
これらの手順を実践し アプリ ユーザー そして機密データを保護してください ありがとうございました
-