分類
Android 安心出行 小鴨幹線

「安心出行」能否安心使用?(三)

上文,這部份看看下載及通知與感染者接觸的功能,以及相關的問題。

下載組態及資料更新

下載設定及權限

第一部份所提及,程式使用了 react-native-background-fetch 做背景下載。值得一提的是,其下載設定為

{
  minimumFetchInterval: 15,
  requiredNetworkType: l.default.NETWORK_TYPE_ANY,
  stopOnTerminate: false,
  startOnBoot: true,
  enableHeadless: true
}

NETWORK_TYPE_ANY 是指,程式不論是 WiFi 或是流動網絡,只要有連線,均會下載資料作更新。與此相關的是,手動上載的士車牌影像供 OCR 前,亦沒有特別檢查 WiFi 狀態(因為並不預期在的士內可以穩定利用 WiFi [1])。

因此,資科辦解釋「安心出行」權限時 [2] 所指「流動應用程式需要網絡存取、Wi-Fi連線(以節省用戶數據使用)、媒體及檔案相關權限,以保障用戶私隱」,「應用程式需要在背景執行,並使用手機的上網功能,將有關資料定時下載… 。因此,流動應用程式需要網絡存取、Wi-Fi連線、容許程式可以在背景執行及發出通知的相關權限」,具有誤導性:

  • 程式根本沒有特別設定,限制只使用 WiFi 上下載,以節省流動數據,
  • 上述「Wi-Fi連線相關權限 」在前文後理下,可理解為程式要求的 ACCESS_WIFI_STATE(查看Wi-Fi連線)權限及 CHANGE_WIFI_MULTICAST_STATE(允許接收Wi-Fi多點傳播封包)。事實是,若單純使用 WiFi 連線,INTERNET 網絡存取權限已足夠。查看 WiFi 連線權限,是用於取得 WiFi 連接有關的額外資訊,在 Android 6 之前更可取得附近 WiFi 網絡(Access Point)識別資料從而推斷用戶位置。從程式功能看,似乎沒有此權限的必要。[3]

觀乎實際程式碼,似乎是開發商使用了一些涵蓋廣泛功能的程式庫,因而附帶要求了相關 WiFi 權限,與當局所指需要 WiFi 連線或節省用戶數據無關。

組態檔

在下載時,如第一部份所述,程式會先下載一個載有目標檔案資料的目錄,附更新時間(updatedAt),以讓程式自行決定要下載什麼資料(getBatchFile),內容例子:

[
  {
    "id": 62,
    "batchSize": 67,
    "startTs": null,
    "endTs": null,
    "filename": "20201127-1606476888700.zip",
    "updatedAt": 1606476889000
  },
  ...
  {
    "id": 51,
    "batchSize": 0,
    "startTs": null,
    "endTs": null,
    "filename": "20201116-1605499040680.zip",
    "updatedAt": 1605470241000
  }
]

程式接着再下載組態檔(getConfig)。組態檔的內容如下:

{
  "config": [
    {
      "id": 2,
      "type": "DEFAULT",
      "overlapDuration": 60000,
      "groupOnly": false,
      "indirectWithin": 0,
      "indirectDuration": 0,
      "matchingKeyDays": 14,
      "dataRetentionDays": 31,
      "checkOutReminderMs": 3600000,
      "forceUpdateVersion": "0.0.0",
      "appStoreIos": "https://apps.apple.com/us/app/leavehomesafe/id1536377801",
      "playStoreAos": "https://play.google.com/store/apps/details?id=hk.gov.ogcio.leavehomesafe",
      "appGalleryHms": "https://appgallery.huawei.com/#/app/C103081261",
      "enableCI": false,
      "enableFollowUp": false
    },
    {
      "id": 3,
      "type": "TAXI",
      "overlapDuration": 60000,
      "groupOnly": false,
      "indirectWithin": 86400000,
      "indirectDuration": 1000,
      "matchingKeyDays": 14,
      "dataRetentionDays": 31,
      "checkOutReminderMs": 3600000,
      "forceUpdateVersion": "0.0.0",
      "appStoreIos": "https://apps.apple.com/us/app/leavehomesafe/id1536377801",
      "playStoreAos": "https://play.google.com/store/apps/details?id=hk.gov.ogcio.leavehomesafe",
      "appGalleryHms": "https://appgallery.huawei.com/#/app/C103081261",
      "enableCI": false,
      "enableFollowUp": false
    }
  ]
}

程式內的用戶紀錄及下載感染者紀錄都是按 type 分開處理,上述組態檔中,type = DEFAULT 是指預設不同類型場所紀錄的處理,而 type = TAXI 是指的士車牌的紀錄。

  • overlapDuration:60000 (一分鐘),與感染者在同一場所超過一分鐘,會視為直接接觸。
  • groupOnly:未啟用,若啟用時會收窄接觸的定義,除處於同一場所外,要與感染者紀錄的 group ID 相同,才視為有接觸(目前 group ID 全部設為 NO_GROUP,即 “00000000”)。
  • indirectWithin:86400000 (一日,僅用於的士)及
  • indirectDuration:1000(一秒,僅用於的士),若用戶和感染者使用同一的士,即使沒有直接接觸,只須在感染者離開的士後的 24 小時內進入的士,逗留超過一秒,便視為間接接觸
  • matchingKeyDays:14(兩星期)程式下載資料後,只會核對自該日零時對上兩星期起至今的紀錄。
  • dataRetentionDays:31(31日)下載資料後會觸發清除用戶超過31 日的到訪的紀錄。(程式統一使用 type = DEFAULT 的設定)
  • checkOutReminderMs:3600000(一小時)Check in 後一小時會提示用戶 Check out。
  • forceUpdateVersion: “0.0.0”,若有新版本,或會強制用戶更新,暫時(11月底)未啟用。
  • enableCI / enableFollowUp:未啟用,程式內沒有相應編碼。

注意這個組態檔是不會儲存的,每次使用時會重新下載,即是說內容隨時可由當局改變,包括當局掛在口邊,31 日清除到訪的紀錄的設定。此外,forceUpdateVersion 若啟用,用戶要使用程式或須下載新版本,即使現行版本經檢視未有發現問題,新版本仍是沒有保證。特別是 group 配對 / enableFollowUp / enableCI [4] 等功能,目前未有資料,但觀乎名稱,可能日後會如當局所指的「按部就班」,逐步加強追蹤及跟進的功能。

感染者到訪資料檔

根據前述 getBatchFile 所載的目錄資料,程式會下載自安裝或上次更新後,所更新的感染者到訪資料(downloadKeys)。資料是經 base64 編碼及 zip 壓縮的 Protobuf 檔案格式 [5]。

資料解壓及合併後,成為按 type(如 TAXI)分類的感染者到訪資料列表,內容主要是如第二部份所述,經「加密」的 keyData(地點及時間資料)及可用於解密的 keyInterval

而實際下載的有關資料內容,就是政府公布的確診者到訪大廈資料,以下為例子:

inTs: 2020-11-24 00:00:00 outTs: 2020-11-24 23:59:59.999000
metadata: {"name_zh_hk":"置地廣塲","type":"IMPORT","name_zh_cn":"置地廣塲","name_en":"The Landmark"}

inTs: 2020-11-24 00:00:00 outTs: 2020-11-24 23:59:59.999000
metadata: {"name_zh_hk":"公爵大廈","type":"NONGOVBUILDINGOFFICE","name_zh_cn":"公爵大廈","name_en":"Edinburgh Tower"}

inTs: 2020-11-24 00:00:00 outTs: 2020-11-24 23:59:59.999000
metadata: {"name_zh_hk":"告羅士打大廈","type":"NONGOVBUILDINGOFFICE","name_zh_cn":"告羅士打大廈","name_en":"Gloucester Tower"}

inTs: 2020-11-24 00:00:00 outTs: 2020-11-24 23:59:59.999000
metadata:{"name_zh_hk":"約克大廈","type":"NONGOVBUILDINGOFFICE","name_zh_cn":"約克大廈","name_en":"York House"}

注意可能由於資料不是來自程式,出入時間基本涵蓋全日,即只提供日期資料。

程式接下來﹐便是將下載資料按組態檔中的設定核對,以找出是否有與感染者「直接接觸」或「間接接觸」的個案(同一時段及地點同時有「直接接觸」及「間接接觸」,會視為直接接觸,不過在下載資料涵蓋全日看來,這個已沒有太大意義)。有關個案及配對資料會存到 Inbox 內,資料如下:

  • date: 目前時間
  • title: 訊息主題,“Possible COVID-19 Notification”
  • template: 訊息,分為的士及其他一般場所兩種
  • exposedDate: 用戶 Check In 場所時間
  • checkOutTs: 用戶 Check Out 場所時間
  • metaData: 即上文所指的venue資料,如地方種類,名稱及的士車牌,以 JSON 存放
  • diff: 直接接觸:與感染者同處一場所合計時間,間接接觸:用戶處於場所(如使用的士)合計時間
  • uuid: 即時產生的隨機 UUID
  • confirmedKeyData: 下載感染者配對的 keyData
  • contactType: 間接接觸為 “I”,直接接觸為 “D”
  • isRead: 是否已讀

若有發現新的接觸個案,會向用戶發通知,更新首頁的通知總數資料。

順帶一提,下載資料 zip 檔案及解壓檔案會即時清除,核對後只會存放成功核對的相關資料到 Inbox。當中由於沒有存放感染者的 keyInterval,在 Inbox 中的感染者配對的 keyData
只能用來當 hash 用,以確保不會重覆通知,但不能還原資料。

另一方面,程式內雖有清空 Inbox 功能的編碼(deleteInbox),但似乎沒有使用,讀取後只會劃為已讀。一旦 Inbox 有接觸感染者的訊息,可能除了清除 App 所有資料或重裝外沒有方法消除。

問題是,Inbox 訊息總數是當眼地顯示在程式首頁,如無法清空,而政府場地/私人物業要強制訪客打開此程式,公開地在物業管理員監視下掃描 QR Code,變相是要公開出示這個可以解讀為個人的「感染風險指數」的數字(事實上,程式內稱此數字為 “Exposure Count”)。

可以想像一下,當人人要使用程式,很快便得悉這個數字的「功能」,當「風險高企」者被發現,除了附近人士彈開,同時亦難以排除在監視的物業管理員可能被要求對「風險高企」者有特別對待,如進一步檢查接觸紀錄,否則禁止進入。

這不已經是「健康碼」了嗎?

廣告:不用搶購 3310,Android 2.2 – 4.0.4 不兼容「安心出行」
但可安裝「小鴨幹線」攔截電話

清除舊紀錄

當下載,核對及發出通知完成後,在檢查上次清除紀錄日期不是今天後(每天最多清除一次),程式會清除今天零時對上 31 日(視乎組態檔的 dataRetentionDays )於 LocationHistory 中的用戶到訪紀錄(clearDataOverRetentionDays)。由於紀錄作了「加密」,程式要讀取 LocationHistory 所有紀錄,逐一解密及抽取 Check In 時間作比較,才能決定要清除的紀錄。

此外,如上面指出,Inbox 的與感染者接觸資料沒有清除,這技術上已違反了政府「出行記錄亦會在存放手機達31天後自動刪除」的說法,因為 Inbox 也包含了用戶到訪地點及時間詳情。

下文再看看希望用不到的感染者上載資料功能。


[1] 除非… 「司機唔該跟貼前面架巴士,我要用佢 WiFi 上網」

[2] 全文見新聞稿原文

[3] 即使假設程式要偵測是否正使用 WiFi 連線,以啟動下載,ACCESS_NETWORK_STATE (查看網絡連線)權限已經足夠,「小鴨幹線」便是例子。

[4] CI 相信不是軟件開發的 Continuous Integration,又不似統計方面的 Confidence Interval。

[5] 完全是架床疊屋,原本資料(keyData)已經是所謂加密的 data 加上 base 64 encode,加上 Protobuf ,壓縮空間不大,開發者竟想到用多一次 base 64 encode 發大再用 zip。

在〈「安心出行」能否安心使用?(三)〉中有 1 則留言

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *