Closed nov closed 4 years ago
ご提案ありがとうございます。
UserUuid / Secretは二つの役割を持っていまして。 UserUuid・Secretは発行時にお考えの通りにアプリに格納されています。 SecretはRegister以後のAPIを保護する為に利用している、AES256のキーです。(ユーザー個別に発行されています。)
では、UserUuidは何に利用しているかといいますと、Optoutの為です。 Apple/GoogleのEN実装では、EUでも承認されたものの本来はGDPRが考えるOptoutが対応されていません。 よって、Optoutの考え方が無い為、サーバ側は一度送信された診断キーを14日間保持し、クライアントに送信された診断キーがシーケンシャルに読み込まれます。
この過程と同様に私たちも考えたのですが、本来論のGDPRに対応する為にも、14日間経過前に削除するというOptoutがあったほうが良いのではないか?との考えに至っています。(もちろん本来の実装にはありません。) この点は私たちもとっても悩んだところでした。
Optout APIはサーバ側は配備されており、今後クライアントに実装する予定ですが、このAPIの呼び出しによって該当UserUuidとSecret、そして診断キーをDBから全削除し、ユーザーが送った一切のデータは削除される仕組みとなっています。
廃止される事によって、GDPRには準拠できなくなるのですが、この辺りのお考えと他に良い方法などあれば私たちもうれしいです。
optoutと言っているのは、何のoptoutのことでしょうか?
ユーザー自身の登録データの削除です。 Optoutによって、こちらのDBからはUserUuid / Secret / アップロードされた診断キーのユーザーすべてのデータを削除してしまいます。
それはTEKリストを送ってそのTEKを削除するのではなく、UUIDを用いて2週間以上の長期にわたってユーザーを識別し続けなければ実現出来ないものなのでしょうか?
TEKリストを送って、クライアント側で削除ってできるのですか?だとすると把握していない可能性があるので、教えてください。
クライアント側での削除ではなく、クライアントからサーバーに送ったTEKリストをサーバー側で削除したいということではないのでしょうか?
であれば、クライアント側から再度削除してほしいTEKリストを送れば良いかと。
えっと、その場合なのですが、クライアント側から送られてきたTEKがそのスマートフォンのアプリであると、どの様に一致させたら良いでしょうか? そのような仕様ってありましたっけ・・・OS側からAPIで受け取ったTEKは一度送信すると再取得がOSからできないはずでして、アプリ内で保存する事もできなくもないのですが・・・それは出来ればやりたくないのです。
その検証が必要な理由はよくわからないのですが、それを検証する必要があるのであれば、TEK送信後一定期間のみ有効な識別子を生成するのが良いのではないでしょうか。
送信時UUID生成は良いですね。 あとはSecretなのですが、これは残したままになりますが、どうしましょうか・・・ その場合、RegisterAPI以外のAPI保護方法を再検討する必要があるのですが、どうお考えになりますか?
どのAPIをどういった攻撃から保護したいのかはよくわかりませんが、API保護よりも14日以上永続化されてしまう識別子を排除することが求められているアプリかと思います。
陽性登録APIです。 陽性登録は非常にリスクの高いAPIで、場合によってはテロ行為として扱われ、パニックを意図的に起こすなどの懸念もあります。既にAPIレベルのキーは、本日のリバースエンジニアリングを行われたホワイトハッカーの皆様で破られています。クライアント証明書の導入は検討していますが、これもリバースエンジニアリングで破られます。 無い場合は、いわゆる丸裸で運用する事になるのですが、他に何か良い策ありませんでしょうか?
そのために「処理番号」なるPINのようなものを発行しているのではないですか?
現状UUIDやSecretはRegister APIさえ叩いてしまえばいくらでも発行できるようなので、特にSecret単位でアクセス数等を制限しても効果は見込めないかと思います。
この点については、私たちだけでの判断では、ちょっと厳しいので、この提案について政府の担当さん通じて少し相談するお時間をくださいませ。
ちゃんと追わないでやや無責任な言説なのでおかしければ聞き流してください。送信時にuuidを送りシークレットで認証するより、送信時に鍵ペアを生成して、公開鍵を識別子として送信、APIアクセス時にはnonceを含むリクエストにsecure enclaveで保護している秘密鍵で署名して送ればよくありませんか?破るのはかなり困難になると思いますが。
鍵ペアである必要もないかと思います。 Diagnose APIで送信するデータにクライアント側でランダムに生成したtokenを添えておき、OptOut APIでも同じtokenを送ってもらって、サーバー側ではtokenに紐付いたTEKリストのみ除けばよいのでは。
ご意見、ご提案ありがとうございます。
現行のSecretを削除するとき問題点として以下の認識です。 (まだほかにもあったらごめんなさい)
DignosisApiの保護が薄くなる。 Secretでの案として、古典的ですが、Uuidによる連続したアクセスによる攻撃、ブルートフォースアタックに対応する。生成時から一定期間は自己診断登録を拒否するなど。
悪意あるユーザーによってDignosisApiから呼び出されるサービスに負荷をかける可能性がある すべてを丸投げすることもできなくはないですが、呼び出されるサービス側がそれを拒否しなければいけない状況を生み出す可能性があります。
DiagnosisApiに提出した内容を削除できなくなるか、他人の登録したデータを勝手に削除できてしまう可能性がある。 個別Secretでの案として、OptOutのための自己診断データに対する利用者の権利と保護を考えていました。
ご提案として3.の解決策をいただきました。 しかしながら、1.および2.の対策が弱い状況なので、このままでは踏み込むのは難しいと考えています。
処理番号に電子署名を付けてフロントエンド内で検証できれば1,2についても解決できそうですが、その部分を変えるのは難しいでしょうか? 現状の数値8桁の番号では虚偽申告を排除できず、どのみち拡張する必要があるように見えます。
@tzik さんが仰るように、1, 2 は、より確実な形で解決できています。
単に(bearer) token でよいのではないかという点については、想定する攻撃者モデルによるということになります。テロを想定するのであれば、かなり強い攻撃者を想定することになるので、送信されたトークンは読むことができるnetwork attacker を想定すると思います(名前に反し、必ずしもトークンはネットワーク上で読まれるとは限りませんが)。このような場合、上記のような鍵ペアの利用は有効です。
すいません。私が理解に至ってないようです。
電子署名の元となるものは、公開キーになるということでしょうか? それとも、最初の段階でUserUuidに代わり秘密キーを発行するということでしょうか?
単に(bearer) token でよいのではないかという点については、想定する攻撃者モデルによるということになります。テロを想定するのであれば、かなり強い攻撃者を想定することになるので、送信されたトークンは読むことができるnetwork attacker を想定すると思います(名前に反し、必ずしもトークンはネットワーク上で読まれるとは限りませんが)。このような場合、上記のような鍵ペアの利用は有効です。
ユーザーデータの保護という意味での、トークンを読むことができるという点については確かにそうで、これはクライアント証明書によるエンドポイントの保護を考えています。 クライアントに公開証明書を用いて、サーバーに秘密キーを持つ証明書でのTLSを用いると。
問題としての1と2は、 陽性登録API(DiagnosisAPI、自己診断提出API)は悪意あるユーザーからのアプリ全体の保護で、利用者全体に対するものと考えています。これを実現するために、個人情報を含まない形での識別がSecretというものにもなっています。匿名アクセスを前提とする場合、平等であるがゆえに誰でもアクセスすることができる。つまり、攻撃をそのまま受けてしまうことを意味していると考えておりました。 前提としてアプリに埋め込んだリソースは抜き出すことが可能で、これは公開した情報と同等と考えています。
すいません。私が理解に至ってないようです。
電子署名の元となるものは、公開キーになるということでしょうか? それとも、最初の段階でUserUuidに代わり秘密キーを発行するということでしょうか?
言葉足らずでしたね。すみません。 感染者管理システムが鍵ペアを持ち、検査陽性者には電子署名付きの処理番号を発行し、陽性者登録APIに渡してもらいます。 Diagnosis APIの受け口には公開鍵を持たせておき、陽性者登録時に署名の検証をし、正当でないものは棄却します。 署名付きの登録番号を持たない攻撃者に対してはそのまま棄却し、登録番号を持つ攻撃者に対しては、番号ごとにrate limitをかけるか、使用回数に上限をつける、というのを想定していました。
@tzik さんが仰るように、1, 2 は、より確実な形で解決できています。
単に(bearer) token でよいのではないかという点については、想定する攻撃者モデルによるということになります。テロを想定するのであれば、かなり強い攻撃者を想定することになるので、送信されたトークンは読むことができるnetwork attacker を想定すると思います(名前に反し、必ずしもトークンはネットワーク上で読まれるとは限りませんが)。このような場合、上記のような鍵ペアの利用は有効です。
MITMが成立している想定でのモデルはあまり考えたくはないのですが、その想定だと送った公開鍵がすり替えられることまで気にする必要がありませんか。
1, 2 については、保健所から発行される処理番号が保護の役目を果たしていると認識しているのですが、違いますでしょうか?
感染者管理システムが鍵ペアを持ち、検査陽性者には電子署名付きの処理番号を発行し、陽性者登録APIに渡してもらいます。
電子署名である必要はありますか?処理番号が十分に推測困難ではないとしても、スマホの操作に不慣れなユーザーでも簡単に入力できるように、8桁くらいのパスワードを組み合わせるので十分ではないでしょうか。
感染者管理システムが鍵ペアを持ち、検査陽性者には電子署名付きの処理番号を発行し、陽性者登録APIに渡してもらいます。
電子署名である必要はありますか?処理番号が十分に推測困難ではないとしても、スマホの操作に不慣れなユーザーでも簡単に入力できるように、8桁くらいのパスワードを組み合わせるので十分ではないでしょうか。
悪意あるユーザーによってDignosisApiから呼び出されるサービスに負荷をかける可能性がある
らしいので、裏にあるサービスにアクセスすることなく正当性を検証できる必要があるように思えます。
「裏にあるサービス」とはなんのことでしょうか?
現時点で、私の認識として、技術的には @tzik さんの方法が理想的だと思っています。 しかしながら、多くの人に使ってもらう点を踏まえるとUI/UXの考慮が必要になるのも現実です。 総合的に見たとき、裏側のシステムとの兼ね合いは課題がある点と、利用者に手間をかけられないというのがあります。
論点ではないですが、自らの意思でインストールしてくれた人に対して重要な陽性登録を含めたアプリ全体を保護できていないというのはつらいものがあります。
裏にあるサービスにアクセスすることなく正当性を検証できる必要があるかどうかは全体アーキテクチャの問題であって、それは識別子設計を行った結果変更が必要になるものではあるかもしれませんが、まずはその制約に引っ張られずに政府関係者・有識者会議交えて現状の識別子設計そのものの是非について議論されるのがよろしいかと思います。
その結果「2週間以上ユーザーを追跡可能な識別子は存在するが、それはユーザーに不利益を及ぼすようなトラッキングには利用しないことを宣言することで現状の仕組みを維持する」というような議論も可能かと。
陽性報告をした時点で既存のSecretを捨ててもう一度Secret (次回報告用)を取得するのはどうでしょうか。
多くの人に使ってもらう点を踏まえるとUI/UXの考慮が必要
この点だけを取り上げるとそうだと思いますが、
本 Issue は userUuid および secret の廃止
が主題であり、
UX については一旦分けて考えるのが良いと思いました。
議論の主題については一貫させたほうが良いかと。
虚偽報告の検証は、現状UUIDはほとんど全く対策になっていない(UUIDを大量生成してから大量報告が可能)ので、別のIssueに分けた方がいいかもしれません。
現状の数値8桁の番号では虚偽申告を排除できず、どのみち拡張する必要があるように見えます。
参考までに、処理番号の桁数のみで虚偽報告から保護する場合、DP-3Tだと64 bitのエントロピー(数字のみの場合は20桁)を推奨していますね。
4桁ごとにハイフンを入れて5つ入力するくらいですね。
まだissueが分かれていないのでここに記してしまいますが、処理番号の提供が文書や口頭ではなくSMSかメールでの通知に限られるという場合は、ユーザによる手入力を伴わないインテント時のパラメータとして電子署名か(生存期間が短くて情報量が十分に多い)一時トークンを渡せるのかなと(SMSは長さ的に無理かも)。 インテントを使うことで別の考慮点が増えるかもしれませんが。
あるいは処理番号の入力を8桁の数値手入力ではなくアプリからのQRコード読取りとすることで情報量が増やせそうな気もします(運用に面倒な部分が増えそうですが)。
@nov
その結果「2週間以上ユーザーを追跡可能な識別子は存在するが、それはユーザーに不利益を及ぼすようなトラッキングには利用しないことを宣言することで現状の仕組みを維持する」というような議論も可能かと。
個人的には同感ですが、「政府は信用できない」という立場の人には不十分かと思います。
はい、そういった意見も含めて、このアプリに閉じずに政府関係者・有識者会議等を巻き込んで議論していただくのが良いかと思います。
たくさんのご意見をありがとうございます。
少し話が大きくなってきたところではありますが、 私たち(みなさんも?)の立場を明確にしていませんでしたが、あくまでCovid19Radar のコミュニティメンバーという位置にいます。 よって、このコアとなるコードそのものに関してメンテナンスをすることはありますが、 それがCocoaに反映されるかどうかはまた別の話になってきます。 政府またはCocoaという話になったとき、私たちは直接関与できない位置にいることはまず明確にしておきます。
またここで政府に対しての評価や疑問という議論は少し目的がずれているため、純粋なここのソースコード上の問題点とその改善点に留めておくことを前提としたいと思います。 重ねて、政府またはCocoaに対してのご意見ご提案はここではなく、直接お願いいたします。
また、ここではソースを公開しているため気になるキーワードを露出していたずらにソースコードをいじるということはあまり適切だとは思いません。というのも検証可能とするためのソース公開であって、ソースコード、表現およびコメントがなぜ問題であるかという点は重要であります。ですから、問題点の真相を理解するための議論を好みますが、いたずらに問題点だけを列挙してしまうのでは何も答えが出ずに終わってしまうと思っております。
今回の件は、UserUuidが個人情報ではなく識別子としてプライバシーポリシーに明記されていないのが問題ではないか?という提起と受けて止めておりますが、これをここで修正する案が出ない場合は、私たちは関与できない立場になることをご留意ください。
userUuid および secret が導入された目的は、「オプトアウト(サーバーに記録されたTEKリストの削除)」と「虚偽申告の防止」の2点だと理解しています。 虚偽申告の防止に関しての議論は #535 に譲るとして、オプトアウトは本当に必要な機能でしょうか?
まず、オプトアウトの手段を提供するより、Diagnose API を利用するユーザーに対して同意のフローを整備するべきです。 Diagnose API を利用するユーザーは、利用にあたって「TEKリストをサーバーに送信すること」「TEKリストが14日間保存されること」に同意しているはずです。 あとからやっぱり削除したいというユーザーが出て問題になるようであれば、「14日間経過前に削除することはできないこと」を同意の条件に加えるなどして、オプトアウトが必要な事態を未然に防ぐべきだと思います。
また、オプトアウト自体技術的に非常に困難で、実現不能だと思います。 陽性判定がでたユーザーのTEKリストは、そのユーザーとの接触があったか否かを判定するために、アプリを利用するすべてのユーザーで共有されます。 一度共有されてしまったTEKリストは、サーバーから削除されたとしても、ユーザーの手元に残り続けます。これを完全にコントロールすることは不可能です。 このような技術的制約がある以上、TEKリストとユーザーを紐付けるようなトラッキングIDを発行することは、第三者によるトラッキングの危険性を高めるだけです。 サーバーに送信したTEKリストはユーザーのスマホから即時削除すること、トラッキングIDとして利用されかねない userUuid および secret は廃止することが、一番安全で確実だと考えます。
すいません。 少し誤解を生んでいましたが、TEKリストとUserUuidは公開時には紐づけが失われ複数人のTEKでランダムに並び替えられたものになっております。 TEKは、定時バッチによって公開用のファイルにまとめられます。 よってそれまでの限られた時間に抜け出すができる選択肢を残しておいたものになります。 まとめられた後の公開されたexport.bin export.sig および zip にUserUuidが紐づくことはありません。
少し誤解を生んでいましたが、TEKリストとUserUuidは公開時には紐づけが失われ複数人のTEKでランダムに並び替えられたものになっております。
一般公開はされないまでも、サーバー上で TEKリストとUserUuid の紐付けは行われるわけですよね?
この紐付け情報はユーザーのプライバシーに関わる非常にセンシティブな情報です。 医療関係者やユーザーにとって、Cocoaの運営団体は Apple や Google と同じく、Exposure Notificationsサービスを提供するだけの第三者組織という立場だと思っています。 Apple や Google がプライバシーに関する情報を保持しないのと同様に、Cocoaの運営団体もこれらの情報へアクセスするのは極力避けるべきだと考えます。
よってそれまでの限られた時間に抜け出すができる選択肢を残しておいたものになります。
時間が限られているのであれば、余計に事前の同意をしっかりと行うべきです。 不完全なオプトアウトの仕組みによって、ユーザーのプライバシーを危険に晒すわけにはいきません。
個人情報保護法の観点からは、事前に定められた14日間という期間で、サーバーおよび各端末から、確実に削除されるのであれば、同意文書にその利用期限が明示されており、利用者が同意すれば問題ないかと思います。
そうですね。APIとして実装を進めていく中で、Export.bin の仕様は明確になりまして、再作成ではなく増分作成となり、またパフォーマンス?への懸念から総入れ替えは困難(1日あたり15ファイル)という制限もENの仕様書にあった気がします。
よって、現時点で封鎖してしまったほうが良い機能ではありそうです。 あとは、陽性登録の保護をどうするかで動けそうではありますが。 何かコードで語りたい方がいらっしゃればそれでも良いかもしれません。
UserUuidが個人情報ではなく識別子としてプライバシーポリシーに明記されていないのが問題ではないか?という提起と受けて止めておりますが
元々の問題は、
これらの識別子およびトークンは14日間というスパンを超えて永続的に利用可能な識別子であり、Apple / Googleが14日間を超えたトラッキングを防ぐために採用している識別子発行ポリシーに逆行しているように思われます。
とあるように、14日を越えて追跡可能なIDを送ることで14日を越えてトラッキングができてしまうというものでした。
ここでsecretが変わらないことでどの程度トラッキングができるようになるのか検討してみます。
これはできません。secretは第三者には公開されません。
ユーザが2回以上陽性と判定されて、都度TEKをアップロードした場合に、各アップロードが同一人物によるものであると判定できるので、トラッキング可能となります。 しかし、日本の場合は「新型コロナウイルス感染者等情報把握・管理支援システム (HER-SYS)」に氏名住所などを登録した上で、そこに登録された電話番号(SMS)またはメールアドレスに向けて処理番号を送信します。 https://www.mhlw.go.jp/content/10900000/000641655.pdf そのため、政府や関係者が悪意を持っていた場合、個人と処理番号の対応を記録しておき、複数回のアップロード間をリンクさせることがsecret無しに可能です(あくまで原理的には)。
つまり、もともと悪意を持った政府や関係者はアップロード間のリンクが可能なので、secretの導入によってより悪くなることはありません。
ただし、secretが無い場合は通知サーバの管理者とHER-SYSの管理者が結託する必要があるのに対して、secretがある場合は通知サーバの管理者のみでトラッキングができてしまうという違いはあります。
A: もともとsecretの有無にかかわらず悪意を持った政府は複数回のアップロードをリンクできてしまうのだからそのままにする。 B: secretがあったとしても虚偽報告は多少コストが上がる程度なので無くしてしまう。 C: secretをアップロード毎に更新する。通知サーバ側を変更しなくてよいのでその分楽である。
繰り返しになりますが、私個人はBを推します。
B. secretを無くす
ただし、secretが無い場合は通知サーバの管理者とHER-SYSの管理者が結託する必要があるのに対して、secretがある場合は通知サーバの管理者のみでトラッキングができてしまうという違いはあります。
この点は非常に重要だと思います。 関係者に悪意を持っている人がいるとは思いませんが、常に万が一を想定するべきです。 悪意を持った人間が通知サーバの管理者にいた場合、それを止める人間が他にいないというのは問題です。 このアプリは一人でも多くの人に利用してほしいアプリなので、安全性・透明性の確保が第一だと思います。
陽性報告以前にはUserUuidはだれとも共有されないとう理解であっていますか。
私も #535 とセットでBを押します。 なによりも仕様がとても明快です。 これも疑心暗鬼を防ぐには重要なことかと思います。
他方で、冒頭の理解のもとでは、陽性確定後に政府関係者に追跡されうることは大きな問題ではないようにも思います。 むしろプライバシーを一部犠牲にして積極的にクラスター班が活動するフェーズだからです。
陽性報告以前にはUserUuidはだれとも共有されないとう理解であっていますか。
わかりにくくてすいません。 共有することがないはずです。 生成しているコードはここです。 https://github.com/Covid-19Radar/Covid19Radar/blob/master/src/Covid19Radar.Api.Common/Services/CryptionService.cs
その他API上で、Http Request の Header に埋め込まれるTokenとして扱っています。 検証が以下で https://github.com/Covid-19Radar/Covid19Radar/blob/master/src/Covid19Radar.Api.Common/Services/ValidationUserService.cs
Secretとペアで使っているためどちらかを消すというよりセットで消すというものになります。
個人情報保護の観点からは、Bが望ましいです。政府のクラスター班の追跡を行う場合には、個別に陽性者に同意をとるべきだと思います。可能であれば、陽性者が申請する際に、処理番号を秘密鍵で署名して送るのが望ましいかと。秘密鍵が漏洩しなければ、不正もかなり防げると思います。
なるほど、クラスター班は別途同意のほうが、ずっとアプリ普及には良さそうですね。
秘密鍵で署名して実質的な処理番号長が伸びるぐらいであれば、#535 で良いのではないでしょうか。
処理番号は、そのまま送信して、別途署名を送るのが現実的だと思います。 陽性者が検査結果を通知される際には、PCR検査という物理接触があるので、ここで鍵やシークレットを交換しておくのがよいのでは? 理想的には、PCR検査の結果も、検査から陽性判定までにタイムラグがあるので、このアプリを通じて、通知される仕組みになれば、陽性者が導入する可能性は高くなると考えられます。
ここでは厚労省のポリシーや保健所が発行するコードの仕様変更を伴うような全体アーキテクチャに関する議論を行うのはあまり効果的ではないようなので、こちらのツイートで公開されている厚労省の連絡先に連絡させていただきました。 https://twitter.com/kazumihirose/status/1274639502716198914?s=21
こちらから Close してしまって良いのか判断しかねますが、個人的にはこれはこのオープンソースアプリ単体で解決できる問題とも思っていないため、私としては Close いただいて結構です。
現在アプリ初回起動時にuserUuidという永続的なアプリインスタンス識別子と、それと1-1で紐づくsecretというトークンを発行して、感染報告時にTEKと同時にそれらをサーバーに送っています。
これらの識別子およびトークンは14日間というスパンを超えて永続的に利用可能な識別子であり、Apple / Googleが14日間を超えたトラッキングを防ぐために採用している識別子発行ポリシーに逆行しているように思われます。
これらの識別子およびトークンの利用を撤廃してはいかがでしょうか?