ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Notarization(認証)について
Notarization(認証)は、App ReviewやMac App Storeへの提出を要求せずに、悪意のあるMacソフトウェアを事前に特定してブロックするためのものです。この認証は昨年導入され、すでにMac Appデベロッパに広く利用されています。このセッションでは認証のワークフローについて詳しく説明し、認証サービスの新機能を紹介します。
リソース
- Resolving common notarization issues
- Signing Your Apps for Gatekeeper
- Xcode Help: Upload a macOS app to be notarized
- プレゼンテーションスライド(PDF)
関連ビデオ
WWDC23
WWDC22
WWDC21
WWDC20
WWDC19
-
ダウンロード
(音楽)
(拍手) こんにちは ご来場ありがとう Trust and Executionチームの ギャレットです 今日は“公証”の話をします
まず始めに 内容とそのメリットについて解説します それから 公証に必要な アプリケーション要件と ワークフローやツールについて 確認していきます
まず公証とは何なのでしょうか 昨年のWWDCで説明したように 公証は 悪質なソフトウェアを 配信前にブロックするプロセスです Developer IDプログラムの 機能拡張なので 別の登録や証明書は不要 これまでどおり 自身でソフトウェアの署名や 配信の管理もできます
鍵となるNotary Serviceは 署名済みコンテンツの セキュリティチェックを自動で行います
ではソフトウェアが公証を受ける ワークフローを説明します
図をご覧ください 開発に関するワークフローは 従来と何も変わりません ソフトウェアをビルドし RC版前にApple Developer証明書で 署名します
次にDeveloper ID証明書で署名し Notary Serviceにコピーを提出します 公証が問題なく完了すれば Notary Serviceから チケットが送られてきます
それをソフトウェアに添付すれば 配信の準備完了
ここまでは去年と同じ内容なので 復習になります
違いは この後 ユーザの手に渡った時に起きます ユーザがソフトウェアをダウンロードし 起動する際― Gatekeeperによる検証があります
CloudKit経由でNotary Serviceに 問い合わせてチケットをチェック チケットがアプリケーションの コンテンツと一致すれば 起動が許可され プロンプトが表示されます 公証とはApp Reviewではありません 自動のセキュリティチェックなのです
昨年の目標はNotary Serviceの 応答速度を1時間以内にすること 結果 1年間を通して― 申請の99%に対し 15分以内に応答しました
Notary Serviceの状況は Appleのステータスページに公開され 問題の有無を 簡単に確認することができます
次は公証のメリットについて たくさんありますが 今日は4つご紹介します 1つ目は 悪意あるDependencyの 出荷の防止
2つ目は Hardened Runtimeによる 安全性の向上 後述しますがアプリケーションが 悪用されるのを防ぎます
3つ目は Appleの検査を受けることで ユーザからの信頼度が上がること
4つ目は 公証済みソフトウェアは 監査証跡が記録されるので 提出履歴を確認すれば 不正配信されていないかが― 確認できます
以上が概要です ではアプリケーション要件については ロバートから ロバート
(拍手)
まず すでに配信された ソフトウェアですが 現状のまま公証を受けられます 新しいソフトウェアに関しては いくつかのセキュリティ要件を― 満たさなければ 公証は受けられません 特に署名と Hardened Runtimeの導入は重要です 新しいソフトウェアとは 署名が2019年6月以降のものです
署名とHardened Runtimeについて― これから詳しく話していきます まず署名は とにかく全部に必要です バンドル Mach-O インストーラパッケージ これら3つは 構成関係に関わらず署名が必要です お手持ちの製品にある場合は 見つけ出して正確に署名してください バンドル Mach-Oに加え コードにも署名は必要です コードの説明は後ほどしますが
Developer IDアプリケーション証明書の 署名と secure timestampも必要です
Hardened Runtimeについては 実行ファイルにのみ 有効にしておいてください
インストーラパッケージは Developer IDインストーラ証明書で 署名を Developer IDアプリケーション証明書 ではありません ディスクイメージは secure timestampと Developer IDアプリケーション証明書 での署名が必要です
パッケージのビルドにXcodeを使えば コード署名は すべて自動でやってくれます ただし Script Build Phaseか Copy Build Phaseを使う場合 Xcodeが未確認のコードを導入する 可能性もあるので要注意です 署名が正確であるか 確認しましょう
では コードについて 何年か前にコード署名を導入した際は コードプレースという名称で 呼んでいました コード署名インフラはプレース内の 全ファイルをコードと見なすため 署名の添付が必要です
Mach-Oを使えば プレース内のMach-Oに 署名を埋め込めます ファイルがJPEGや rbfファイルなどの場合でも やはり署名は必要ですが 署名は添付できないので 拡張属性を設定しなくてはいけません コードをパッケージする時は 拡張属性があるか確認しましょう こうした面倒を避ける方法もあります Mach-Oや Mach-Oを含むバンドル以外のものを プレースに置けばいいのです
Xcodeを使わず正確に署名するには Inside-out署名が最適です つまり最初に アプリケーションの最深部にある― バンドルやコードに署名するのです この図で言うと “WatchingGrassGrow.app”内の “Sparkle.framework”にある “Updater.app”です
次にそこから さかのぼって 署名していきます まずは“Updater.app”と Sparkleのメインの実行ファイルを含む “Sparkle.framework”に 次に“WatchingGrassGrow.saver”と “growGrass.dylib” さらに“WatchingGrassGrowHelper”に 最後はトップバンドルで まとめて署名すると バンドルのメインの実行ファイルに 署名されます
カスタムワークフローで “--deep”を使う場合は要注意 “--deep”はコードプレースでしか コードを捜しません 図の場合“growGrass.dylib”や “WatchingGrassGrow.saver” “Updater.app”を コードと認識しないのです 3つは リソースとして署名され 公証を受けるには Inside-out署名が必要となるでしょう
Inside-out署名と コードプレースの詳しい話は 後ほどします
バンドルとソフトウェアに 署名した後は― 署名を無効にしないでください つまりファイルの変更は インストールと更新の間だけに限定し 更新後は 署名が有効か 公証を受けているかを確認してください
Hardened Runtimeについては 昨年 紹介しました 今から メリットと設定について― さらに詳しく解説します Hardened Runtimeは macOSのシステム整合性保護を アプリケーションへ拡張します Runtime code signing enforcementや Library Validation DYLD環境変数保護などです これらはデフォルトの機能です iOSには設定できませんが macOS上であれば誰でも設定可能です
Xcodeを使っている場合 導入は簡単です Signing & Capabilitiesタブを開き Hardened Runtime capabilityを 確認してください
そして設定に必要な エンタイトルメントを選択し チェックを入れます
カスタムワークフローの場合ですが Hardened Runtimeの導入には “--sign”を コード署名するには “--options runtime”を実行します またsecure timestampの確認には “--timestamp”を使います
Hardened Runtimeの導入検証には “--display --verbose=2”で コード署名します その後 flagsセクションの “runtime”を確認します Hardened Runtimeは バージョン管理され どのバージョンに署名したかが 記録されます 今後 Hardened Runtimeに 保護を追加する場合に アプリケーションをテストした バージョンにだけ適用するためです
次はRuntime code signing enforcementについてです コード署名なしの実行メモリが 作成されるのを防ぎます
ディスクを読み込む際 マップされたバイトが コード署名と一致するかを 確認するのです Mach-Oの実行領域だけでなく 非実行マッピングが含まれます
署名が一致しない場合 実行できなくなります ディスクから読み込んだメモリに 変更がないか確認し 実行中 プロセスの整合性を 確かめてください
Runtime code signing enforcementの 難しい事例の1つは JITを使い 非ネイティブなコードを 速く動かしたい場合です “allow-jit”エンタイトルメントを 使うのがお勧めです そしてMAP JITフラグを使用して 匿名のRead/Write/Executeメモリを 割り当てます これにより スクラッチ領域メモリが ある間は システム内の全メモリの保護が 維持されます
JITエンジンにつながる ソースコードがなく MAP JITフラグを 導入できない場合は “allow-unsigned-executable-memory” エンタイトルメントを使います これによりRuntime code signing enforcementの セキュリティ予測が下がります それから ディスクからマッピングしたバイトと 関連のあるコード署名を照合します ただし これによりプロセス内で メモリを変更したり 無署名の実行領域を 作れるようになります
では別の問題を見ていきます Hardened Runtimeの導入後にロードした システムフレームワークを 修正しようとする場合です 基本的には修正せずに Hardened Runtimeが原因を 解決するかどうか見てください ただし どうしても修正が 必要であれば “allow-unsigned-executable-memory” でメモリページを変更できます
Runtime code signing enforcementの 別の問題です 更新中にアプリケーションが 停止した事例 原因はコード署名が初回に カーネルでロックされたことです つまり実行中の署名済みファイルを 変更したため カーネル内の署名と一致せず コード署名違反となったのです 解決法としてディスク内の 既存ファイルを変更するのではなく 新規ファイルを作成し 既存ファイルは破棄します 新規ファイルが初回使用時に 署名されるので コード署名違反にはなりません
次はLibrary Validationです
アプリケーションをインジェクション 攻撃やdylibハイジャックから守るため チームかAppleが署名したコードのみを ロードしているか確認します Appleのコード署名が必要な理由は オペレーティングシステムの 全フレームワークと全ライブラリに Appleが署名しているからです またLibrary Validationは Ad Hocの署名コードや 無署名コードをブロックします 開発中は 無署名にせず Apple Developer証明書で 署名してください
次はLibrary Validationにより 製造過程のプラグインを ロードできないケースです アウトプロセスの プラグインモデルに移動すれば 未確認のサードパーティコードを ロードせずに済みます また“disable-library-validation”を 使えば 無署名のプラグインをロードできます ただし このエンタイトルメントは Library Validationを無効にし Runtime code signing enforcement なしで取得します Ad Hocや無署名の プラグインをロードすると プロセスのセキュリティは下がりますが 必要なら仕方ありません
次はDYLD環境変数保護について
DYLD環境変数は 開発過程では とても役に立ちます テスト中に デバッグライブラリをロードしたり 開発途中のライブラリや テスト段階のフレームワークの― 使用を可能にします それは裏を返せば危険とも言えます 攻撃者がアプリケーションの データを入手し 利用することも可能になるからです ですので Hardened Runtimeは これらの変数をブロックします デバッグ中にDYLD環境変数を 使いたければ “get-task-allow”エンタイトルメント を使用します Xcodeは自動で デバッグビルドに付与し リリースビルドで取り除きます ただ カスタムワークフローを 使っている場合 Notary Serviceは“get-task-allow” 付きバイナリを認めません リリースビルドを提出する前に このエンタイトルメントを 外してください
顧客へ出荷する際 アプリケーションに― DYLD環境変数を 使用した例が数件ありました アプリケーションが 悪用される危険があるので これは やめてください “allow-dyld-environment-variables” エンタイトルメントを使えば Notary Serviceは公証します
ではDebugging protectionについて
デバッガにより プロセスメモリの変更や レジスタやメモリの状態を 調べることができますが 反面 ユーザデータの横奪や 悪意あるコードの注入も可能になります 従って Hardened Runtimeは デバッグを許可しませんが
開発に必要な場合は 再び “get-task-allow”を使います DYLD環境変数と連動し アプリケーションのデバッグを 可能にします ただ アタッチされたデバッガで テストする場合 Hardened Runtime関連の 問題の一部を隠すことがあります Runtime code signing enforcementは デバッガのせいで効力を失うのです デバッガがプロセス内で 自動的にデータを変更するからです それを続ければ クラッシュします Runtime code signing enforcementの 影響をリリースビルドでテストし “get-task-allow”なしで デバッグビルドする場合は “CODE SIGN INJECT BASE ENTITLEMENTS”を“NO”にします これでデバッグ設定は完了です
ロードしたいアプリケーションの プラグインをデバッグする際 プラグインエコシステムでも 同じ問題が起きます その時はアウトプロセスの プラグインモデルへ移動を またはプラグイン開発者を 登録してデバッグ権限を持たせ 彼らにデバッグ版を送るのも 1つの手です
やむを得ない場合は Notary Serviceは “get-task-allow”と “disable-library-validation”の 組み合わせは受け入れます
次はProtected resource access についてです
顧客は 記憶装置として Macに膨大な情報を保存しているので セキュリティに敏感な 情報にアクセスします Hardened Runtimeを導入すると アプリケーションがアクセスする リソースを宣言します 昨年も言ったとおり― これらのリソースにアクセスする際は メインバンドルで エンタイトルメントを取得します それからUsage stringを 宣言してください アプリケーションが リソースにアクセスする時に アクセスの理由を示すダイアログを 表示させて ユーザの同意を得るためです
今までのまとめです エンタイトルメントは 必要最小限に エンタイトルメントは セキュリティを下げます アプリケーションの顧客は エンタイトルメントの役割を 調べられます エンタイトルメントの使用は 必要とするプロセスのみに限定を 複数のプロセスと 複数の実行ファイルがあっても 同じ保護が必要ではありません JITやプラグインのロードを 全プロセスで行いませんよね? 必要なエンタイトルメントのみ 必要なプロセスで
また リソースアクセス宣言中は エンタイトルメントは メインバンドルだけで使ってください バンドル内で他の実行ファイルに 引き継がれていても メインバンドル上だけで大丈夫です では 公証の手続きについて ギャレットに説明してもらいます
(拍手) ありがとう 開発における公証のための考慮事項が 分かったところで 次はNotary Serviceへの 提出方法です
公証のワークフローを説明します Xcodeか カスタムワークフローかに関係なく ワークフローは ほぼ同じです アプリケーションを提出し
Notary Serviceのステータスを確認 公証が終わったら チケットを添付し 最後はチケットの添付と公証を 確認します
提出のタイミングと 提出物についてお話しします 提出するのは 配信する全ソフトウェアです
何度でもアップロードできるので マシン外のものはNotary Serviceに 自由にアップロードできます ただ継続的インテグレーションの アップロードは不要です
チームの誰でも ソフトウェアを提出できます この点は役割を制限した昨年と 異なります
これで提出の準備完了です Xcodeの場合 ワークフローが 組み込まれているため簡単です アーカイブをビルドしたら Organizerを開きます “Distribute App”を選択し 次に“Developer ID”を選択
“Upload”を選択し Notary Serviceにコピーを提出します
プログレスバーが表示されます 完了後 Organizerに戻ると ステータスが“Processing”に 変わっています
提出の手続きが終了後 Xcodeに通知をプッシュします ステータスは “Ready to distribute”に変わり 右下の“Export Notarized App”が 選択可能に そこをクリックすると アプリケーションにチケットが添付され 配信の準備完了です それを後で自分で確認する方法は カスタムワークフローとXcodeの ワークフローと同じです
カスタムワークフローでの提出も Xcode同様 簡単です まずは提出するものを確認します Notary Serviceのフォーマットは ディスクイメージ zipアーカイブ インストーラパッケージです ビルド出力が この3つ以外の場合 提出前に フォーマットを変換してください
zipアーカイブには macOS専用のメタデータを 組み込んでください ツールが不明の場合は dittoと アーカイブユーティリティのサポートを
カスタムインストーラの場合は 注意が必要です 少し厄介かもしれません インターネットの コンテンツを落としたり カスタムパッケージフォーマットを 使っている場合です どちらか1つの場合でも 2段階の公証が必要です まずは コンテンツが ディスクに届いたら 先ほどのフォーマットを使い 提出します 次に チケットを添付し カスタムインストーラを提出します
提出物を確認したところで 次は方法です Xcode 10以降には Notary Serviceと相互作用のある― コマンドラインツールの altoolがあります Xcodeを複数 持っている場合は 10以降を選びましょう “--notarize-app”とともに altoolを使い アップロードするファイルと バンドルIDのパスを入力します Apple IDも証明に必要ですが キーチェーンもしくは 環境変数を使えば パスワードの入力は不要です
公証のアップロード後 “RequestUUID”が示されます これが提出物に対するUUIDです “--notarization-info”と一緒か altoolの一部として プロセスの確認に使います これで 公証が完了した日時と ステータスが分かるのです この例では成功しています ログファイルのURLも重要です 公証が成功しても 問題があっても “LogFileURL”を確認してください ログファイルのURLは有効期間が短く わずか1日です 新しいUUIDを与えておけば いつでも公証の 新しいログファイルのURLを得られます
これは成功例のJSONログなので ステータスは“Accepted”です 失敗した場合は “issues”を確認してください これは成功例なので空欄です 失敗した場合 公証の問題点を表すオブジェクトが 表示されます 例えばバイナリが Hardened Runtimeを未導入だったり 署名が不正確だったり そこを修正すればよいのです
成功していても “ticketContents”の確認を ソフトウェアのパッケージ方法が 分かるかもしれません “ticketContents”には 検知された全バイナリが 表示されています つまり添付したチケットに 含まれている情報です 表示されないものがある場合 原因を解明し再試行してください
Xcodeにしろaltoolにしろ 提出手続きが終了すると Eメールが届きます これには配信準備が完了した旨が 記載されています
次のステップです
チケットの添付にはstaplerを使います これはstaplerの一例と stapleコマンドです パッケージやディスクイメージに 直接 添付する時に使います
zipファイルの場合は ファイルを解凍し コンテンツに添付してください 再び圧縮し 配信に備えます
コマンドラインツールとライブラリは 公証は受けられますが 添付はサポート外なので ご注意を
次は すべてが 公証を受けられたかを確認します 確認したい内容によって 方法は違います チケットを添付されたものの確認には staplerを使います stapler上のコマンドで 適切に添付されたアイテムを確認します
続いて 添付や提出をしなかったものの 確認方法を 説明します 使うのは Gatekeeper搭載の macOSに組み込まれた― spctlコマンドです
何をチェックしたいかによりますが 例えばAppバンドルを調べる場合 spctlコマンドに “--assess”“--verbose” “path-to-app”を入力します これで公証の成否が分かります “Notarized Developer ID”なら成功 それ以外の表示は失敗を意味します
インストーラパッケージを 調べる場合です
“--type”と “install〈path-to-pkg〉”を spctlコマンドに加えます これはソースです “Notarized Developer ID”なら 公証は成功です
次に 署名済みディスクイメージの公証を 確認します
先ほどのコマンドの一部を “--type open”に変えるだけ あとは スライドにある contextを入力します 出力は以前と同じ “Notarized Developer ID”なら 公証は成功です
公証済みステータスのチェックは コード署名コマンドを使います
これが その例です “--verify”や“--verbose” “--test-requirement=“notarized”” “〈path-to-binary〉”などを使います
3列目の“explicit requirement satisfied”から テスト要件が満たされたことが 分かります これでバイナリの公証は確認完了 “explicit requirement failed”と 表示された場合 バイナリは公証に失敗しています
では次の話題に移ります セッションの前半でお話しした altoolは― 他にも利用法があります
それは公証履歴の確認です “--notarization-history”を使うと 公証のため提出した全ソフトウェアが 見られます これはコマンドと出力の例です 提出物すべてに ページ番号が付けられます
短い時間に多くの情報を 詰め込みましたが
次の3点だけは忘れないでください 1点目は Inside-out署名を使い 正確に署名すること これは Gatekeeperによる ソフトウェアの検証や 公証のために重要です
2点目は Hardened Runtimeでの エンタイトルメントの取得は最小限に Hardened Runtimeは アプリケーションと顧客に有益ですが エンタイトルメントは アプリケーションの セキュリティを下げます 取得は必要最小限に
3点目は 公証と チケットの添付を徹底し 全ソフトにGatekeeperを通らせること
公証の詳細をさらに知りたい方は “Notalization”ラボへ この後 4時から始めます 今週は 他に2~3のラボがあり セキュリティ 公証 署名の話をします ありがとうございました (拍手)
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。