自己組一套個人搜尋引擎的構想

最近意識到:

  1. google 搜尋上大部分的中文結果都很糟,很多內容農場之外,也有很多就是賣東西的,偶爾可以遇到內容比較好的網站通常 SEO 都不好所以會被埋在第二頁後面。
  2. 意外發現,其實有時候在 google 搜尋框裡面加上 site:tw ,只搜尋網域是 .tw 結尾的網站,就可以相當有效地過濾上述那些無用的內容。
  3. 不管是中英文的內容,我傾向還是會從幾個固定的「入口網站」去發現其他內容,比如說 Hacker News, Reddit, 聯合新聞網之類的。也就是說,我所看的大部分內容,都是從幾個固定的網站出發的。
  4. 通常被上述這些入口網站連到的內容都有一些特定屬性,或是有些基本的品質保證。而且我的習慣是到了一個網站會順便看看這個網站上面有什麼其他東西,快速看過之後大概可以判斷這個網站的內容品質。

既然如此,我在想,基於這些特性,或許建造一套自己個人用的搜尋引擎在技術上和算力、儲存空間成本上其實是可行的:

  1. 既然大部分我會看的內容都是從幾個固定的入口網站去發現,那麼我的爬蟲其實只需要從這幾個固定的網站出發就好了。
  2. 因為入口網站的數量不會太多,我其實可以手動為每個網站「評分」。也可以為特定的網域評分,比如說 .tw 評分比較高。
  3. 接下來,應該就可以簡單計算出每一個爬到的頁面的分數,比如說如果有被高分網站連到的網頁就自動增加評分。
  4. 傳統的搜尋引擎頁面評分標準也一樣納入參考但是降低權重。

其實想了一想,整個構想就只是在搜尋引擎評分機制上面手動加上個人偏好而已。

這個搜尋引擎其實也不需要很厲害,因為如果真的找不到想要的結果,去用 google 就好了。

之前有調查過一套開源的搜尋引擎 YaCy ,之後再看看他能不能做到我想的事情。

九月學習

又一個月太忙沒記錄,先簡單記一下九月。

全家的友善食光的地圖其實有網頁版

一時興起簡單拆解了一下全家的 app:
1. 有 root 偵測和 SSL pinning ,但可以很簡單用現成的 Frida script 繞過
2. 大部分的功能就是個 webview
3. 有追蹤器 igodigital 和 exacttargetapis.com ,pi-hole 都有阻擋了
4. 最重要的友善食光地圖也是 webview,可以直接用瀏覽器開 https://foodmap.family.com.tw/

GrapheneOS 一週使用感想

試用了 GrapheneOS 一個禮拜的心得:

  1. 完成度意外地很高
  2. Google Camera 可以正常運作
  3. 裝了 GrapheneOS 提供的 sandboxed google play compatibility layer , Google Maps 可以正常登入運作
  4. 在系統設定登入了 Google 帳號,但是內建的通訊錄仍然是空的
  5. 下載 Google contacts app ,仍然無法偵測到系統已經登入的 google 帳號
  6. 最後發現需要使用 Davx5 讀取 Google 日曆的 CardDAV ,通訊錄才能和 Google 同步。同步效果相當好,大頭照都可以正常顯示
  7. 內建的定位服務只能使用 GPS ,沒辦法安裝全系統的 network location provider
  8. Google maps 中無法取得目前位置,應該是因為室內沒有 GPS 訊號
  9. Google Play 版本的 Telegram 可以正常收到推播通知
  10. 系統下拉式通知抽屜和抬頭通知顯示框不知道為什麼沒有圓角,有點醜。

總結:

  1. 整合了這麼多增強的安全功能,大部分的應用程式仍然可以正常使用,真的不簡單
  2. 但是,我本來就不會隨便亂裝應用程式,裝的應用程式也會特別挑來源,挑開源的或是大的開發者發行的。而 GrapheneOS 安全防護所設想的情境,似乎大多是進階攻擊中才會發生,例如增強的 memory corruption 類漏洞防護、隔離的 baseband 這些。
  3. 不過,仍有很多實用的隱私和安全性增強,例如 per connection Wifi MAC randomization, Prevention of dynamic native code execution in-memory 等等
  4. 對我來說,還需要稍微調整使用習慣才能把 GrapheneOS 變成日常用。主要是我很常用 Google maps 定位,這下要改用 openstreetmap 了。
  5. 要安全、隱私地使用 GrapheneOS 比 LineageOS 簡單,因為 LOS 並沒有內建那麼多安全功能,要達到接近的隱私程度,LOS 需要仰賴很多插件(Magisk, XprivacyLua, AFWall, 等等)而 GrapheneOS 幾乎都已經直接內建。但沒辦法仰賴插件去補足 LOS 系統保護比不上 GrapheneOS 的狀況(但這也不一定是個問題,LOS 提供的安全保護說不定已經足夠了)。

最後,我還是決定暫時回去用 LineageOS + Magisk + XprivacyLua 。

本月學習:七月

太久沒寫了,直接升級成本月學習。

Photoprism 開源相片管理程式

原本想要在 RPi 4 上面跑這東西,但索引建立速度超慢,一查才發現這系統會用 Tensorflow 去辨識相片內容然後下標籤。因此決定用桌機來跑,裝好了之後跑了十分鐘,臨時起意看一下 CPU 溫度,居然接近一百度。其實我以前完全不會看 CPU 溫度的,現在發現了,顯然一百度這樣不行啊。所以開始找設備把 CPU 降溫。

換機殼

受朋友建議,因為原本的機殼上沒有風扇,可以先改善機殼內的氣流,CPU 溫度沒有改善的話再換 CPU 散熱器。

因為主機大約是 2014 年組的,因此不打算花很多錢買新機殼,最後選擇了中階的 Cooler Master N400,選他最主要的原因是我硬碟很多顆,有四顆 3.5 吋硬碟和兩顆 2.5 吋 SSD,而且價錢合理,外觀中規中矩不會亂發光,還附兩顆機殼風扇。

結果換完之後,高負載時 CPU 溫度還是一樣高,所以一定得換 CPU 散熱器了。

趁著這次,想要一併解決桌機風扇很吵的問題,仔細聽了一下發現主要的風扇聲是來自電源供應器。拆開來看風扇型號和規格,發現規格寫的噪音居然高達 35 dBA ,很吵,但是風量高達 87 CFM ,實在很納悶為什麼平平一個電源供應器裡面要裝這麼強風的風扇。

換 CPU 散熱器和電源供應器內的風扇

也是受朋友建議,決定要買鐮刀牌的無限五,但去到原價屋現場只剩旋風版,多一百塊而已就買了。雖然是旋風版但散熱效果好像沒有比較厲害,我看 CFM 數字差不多。

電源供應器的部分,隨便買了一個 Cooler Master 120 塊,62 CFM 左右的風扇,安靜很多,27dBA 而已。

換完之後,總算有顯著的降溫效果了。實測讓 CPU 滿載四小時,溫度維持在 65 度左右。

安裝 Kubuntu 但使用 ZFS

2018 年開始,我就使用 KDE 作為主要的桌面環境,但 Kubuntu 的安裝程式至今還是不支援自動建立 ZFS pool,所以這次安裝的方法就是先用安裝 Ubuntu 21.04 在 ZFS 上面,然後再安裝 kubuntu-desktop 套件來切換成 KDE。

Ubuntu 預設的磁碟分割,會建立獨立的分割區給 SWAP ,它會根據主記憶體的大小決定 SWAP 的大小,但上限是 2GB。我因為經常要在數個大型應用程式之間切換,通常會分割和主記憶體等大的 SWAP,要修改這項邏輯,只要在 Live installer 環境當中,開始安裝程式之前,去編輯 /usr/share/ubiquity/zsys-setup 這個檔案就好:

# Convert to MiB to align the size on the size of a block
# original: SWAPVOLSIZE=$(( SWAPSIZE / 1024 / 1024 ))
SWAPVOLSIZE=16384

然後就繼續照常啟動安裝程式進行後續安裝步驟。

ZFS 設定建議,大部分 Ubuntu 安裝程式建立 zpool 的時候都有設定,我只把壓縮演算法從 lz4 換成 zstd 而已,免費獲得兩倍的空間而且幾乎不影響效能還真厲害。

手動設定 zswap

我之前一直都是使用 systemd-swap 這隻小程式來設定 zswap ,但作者有提到,其實現在已經沒有很大理由繼續使用這隻小程式來設定,可以直接使用 /etc/tmpfiles.d 裡面的設定來調整 zswap 參數。

我也是第一次知道 tmpfiles.d 這系統,簡單來說他就是可以依照設定檔自動在不同時機在檔案系統裡面建立、刪除或是寫入檔案和 pipe, socket 等。最常見的用途是拿來寫入 /sys/ 底下的設定。

(待補:之後要補上我寫的 tmpfiles 設定)

在 KDE 當中設定 Firefox 使用 client side decoration

client side decoration 也就是整合標題列、分頁列、視窗控制(放大、縮小、關閉)到一列。看就知道了。

首先要調整 Firefox 設定,啟用 client side decoration。

接下來依照這篇教學步驟操作 KDE 設定就可以了。

接下來我想要研究看看其他應用程式(Spotify, Telegram 之類)要怎麼打開 client side decoration。

升級到 macOS Big Sur

每次升級 macOS 就要擔心 MacPorts 會壞掉,或是又要無聊地改什麼使用者界面,再加一些奇怪的系統限制,所以我留在 Mojave 很久沒升級了。不過蘋果只會維護最新三個版本的作業系統,今年的新版出了之後 Mojave 就會停止支援了,所以還是得升級。

macOS 也沒給我先升級 Catalina 再升級 Big Sur 的選項(現在要載到 Catalina 的安裝檔應該也很麻煩),所以決定直接升 Big Sur。

首先就是超級佔空間,原本 128GB 的 SSD 就很小了,安裝總共需要 30GB 左右的可用空間,害我備份地很辛苦。

然後按下去升級,跑了一個晚上,果然失敗了,進入救援畫面,說是磁碟空間不夠,於是又在 Recovery 裡面刪掉了更多檔案,選擇重新安裝 macOS 。

結果仍然失敗,最後都是卡在蘋果 logo 加進度條的一半。

重試了三次之後,覺得很煩,只好試試先刪除原有分割區,重建新的空分割區,讓安裝程式安裝之後,我再從時光機還原原本的資料。

但根據對蘋果產品不可靠的經驗,從時光機還原也有很高的機率會失敗,所以我先試試看能不能從 Recovery 裡面啟動時光機還原成功(其實我沒有完整確認可以還原,我只讓他跑到開始還原的進度條,沒等進度條跑完就取消)。

接下來就再次刪除重建分割區、選擇重新安裝 macOS,安裝總算成功完成了。

第一次開機就可以選擇從時光機轉移資料,最後確實也移轉成功了。

新升級之後幸好主要的軟體都沒什麼改變,但 macOS 新界面的設計仍有退步:

第一,從觸控板右側滑入可以顯示的通知側板是我很常使用的功能,在通知側板向上滑可以顯示勿擾模式和夜覽的開關,現在都移除了,這兩個開關被轉移到模仿 iOS 上拉控制面板的新元件上面,真搞不懂為什麼這 iOS 控制面板不直接跟右側滑入的通知側板整合就好了 -_-

通知側板的小工具也變爛了,以前的天氣小工具預設是可以一次顯示好幾個地點的現在天氣,點單一地點會展開一週預報。新的天氣小工具會直接顯示一個地點的預報,如果要看更多地點必須要新增第二個一樣的小工具,佔空間。

第二,選單列的下拉選單操作變麻煩

在 Mojave 上面的下拉選單第一個項目就是「開啟/關閉藍牙」,先點了圖示之後滑鼠直接往下移動點第一個項目就可以開啟或是關閉。在 Big Sur ,要先點圖示,然後把滑鼠移動到那個開關形狀上面點選才能操作,直接點「藍牙」那兩個字沒有效果。

莫名其妙,一個選單項目就可以弄好的東西,為什麼一定要加個雞肋的開關。

第三,iOS 控制中心隱藏了很多難以發現的選項。

我找了很久找不到夜覽要怎麼關閉,原來是「顯示器」按鈕可以點!問題是不把滑鼠移到顯示器按鈕上面,他就不會顯示右箭頭提示有更多選項。

然後,沒有辦法把夜覽開關直接放在選單列,原本要開關夜覽只要從右側滑入通知側板,向上滑顯示開關,再關閉開關就可以,現在要 (1) 點 ios 選單圖示 (2) 點顯示器按鈕 (3) 點夜覽開關,雖然看起來步驟數量差不多,但實際操作可是差很多,因為通知側板整片都可以滑動,但要點 ios 控制面板上面的按鈕要瞄準到一個更小的區域。

而且,這個多此一舉 ios 控制板上面按鈕的擺設無法調整。

Big Sur 功能劣化真多。

測試 LineageOS + MicroG

  1. Gmail app 竟然可以正常運作,MicroG 不簡單啊。
  2. 不過 Google Maps 無法登入,似乎是很多新版的 google apps 共通的問題。

閱讀

新發現了《Real Life》

Real Life is a magazine about living with technology. The emphasis is more on living.

讀了兩篇很棒的文章:

Amazon Echo or Google Home. Perhaps this development has been enough to push people from privacy cynicism toward what media scholar Ian Bogost, writing in the Atlantic, has described as full-blown “privacy nihilism,” which presumes an omnipresent regime of surveillance that we can no longer resist and may as well not bother to try. He points to experiences of what we might call the data uncanny — “someone shouts down the aisle to a companion to pick up some Red Bull; on the ride home, Instagram serves a sponsored post for the beverage” or “two friends are talking about recent trips to Japan, and soon after one gets hawked cheap flights there” — that have led users to erroneously conclude that their phones are listening in on their conversations.

As Bogost observes, this is not yet technically feasible, but the fact that this belief persists is itself revealing. Having surrounded ourselves with cameras, microphones, and a panoply of sensors, we now find ourselves enclosed in our own personal panopticon. It doesn’t matter whether anyone is actually watching or listening as long as we can’t be sure that they aren’t. Once the apparatus of surveillance is considered a fait accompli, then some measure of cynicism, apathy, or nihilism may present itself as the only reasonable response.

Youtuber: Technology Connections

開發 Medium.com RSS 產生器

如果有人在用 RSSHub 的話然後想看 Medium 上的文章的話,我開了一個 fork 可以抓 Medium 使用者的文章,還有很多待改進的地方但是先丟出來 https://github.com/pellaeon/rsshub(Medium自己有 RSS,但是只有標題沒有內文)

不過看來 medium.com 還是有一些文章用靜態的爬蟲抓不到全文,像這篇就是,部分的內容是透過 graphql 載入的。

也是看了 medium 的背景流量才知道,光是停留在他頁面上任何操作都不做每秒鐘就會發十個 5KB 的 graphql request….真的是垃圾流量

也產生了一個新專案的構想:自動化的 HTML 內容截取器,用一些 heuristic 自己判斷個別貼文連結,截取文字,然後產生 RSS feed。Newspaper 這個專案已經做完前面那一部分了,後面可能再串個 Flask 產 RSS feed 就好,只是我最近比較少寫 Python 要重新熟悉一下 Flask。

跟我討論

歡迎留言,或是留言跟我要 email 🙂

本週學習 2021/04/28

OSX-KVM 和 macos-Simple-KVM

  • 沒辦法直接 passthrough 單一 USB 裝置,需要利用 IOMMU 功能 passthrough 整個 PCI USB controller
  • 如果電腦上只有一個 USB controller 就不能用了
  • 如果要更新 minor OS release 的話建議先更新 bootloader (Clover/OpenCore)

隱私

科學

本週學習:fcitx vs 鼠鬚管, Nextcloud

fcitx vs 鼠鬚管

升級了 macOS 的鼠鬚管,踩到一個 bug ,依照 @grasonchan 的 workaround 成功解決。額外發現他寫的鼠鬚管外觀設定很不錯,是配合 macOS 內建的輸入法的外觀去設計的,他的 repo 內另有一些不錯的設定可以參考。

Linux 上 fcitx 的外觀一向醜醜的,於是研究了一下有沒有類似的主題可以用,發現沒有。要把鼠鬚管的外觀移植給 fcitx 使用也不太容易,比如說鼠鬚管可以輕易做到輸入框圓角,但 fcitx 還是得靠圖檔

我找到的 fcitx 主題:

製作主題的話可以參考 fcitx-nord-skin 的設定檔,裡面有每個設定值的註解 https://github.com/Yucklys/fcitx-nord-skin/blob/master/nord-dark/fcitx_skin.conf

Nextcloud 相片、筆記、日曆、通訊錄設定

總算是用 RPi 4 4GB 架好一套新 Nextcloud ,之前在 3b+ 上面慢到不行,在 4 上面感覺還可以接受。我是用 Nginx + Postgres + PHP-FPM 7.4。

架完之後發現 Nextcloud 最近發展的很不錯,手機 app 改進了很多。

主 app 採用了跟 Google 雲端硬碟類似的界面:

另外也有筆記 app,可以稍微取代 Google Keep :

Nextcloud 使用上還有幾個問題,像我的相片資料夾是在 NAS 上,全 NAS 是透過 NFS 掛載在 RPi 上面,但是是在 Nextcloud 資料目錄外,所以我一開始使用外部儲存功能把它加進來。但後來發現相片插件不支援外部儲存。暫時的解法是用 mount --bind 把相片資料夾 bind mount 進 Nextcloud 的使用者目錄下,這樣就算是在 Nextcloud 資料目錄裡面了。

另外我也順手修了一些翻譯

手機喇叭太小聲

似乎是第三方 ROM 常見的問題。我安裝了論壇上提供的設定檔之後,麥克風收音又變得太大聲,應該是增益調太高導致 clipping distortion ,所以又嘗試幾次調整出適當的設定

開源的手機天氣 app

https://f-droid.org/zh_Hant/packages/de.beowulf.wetter/

使用 OpenWeatherMap.org ,這個網站的天氣預報是用他們自己的機器學習演算法預測的,而且產出的結果使用開放授權。

本週學習 2021/02/28

Cloudflare Workers

之前有一段時間住處的網路不知道為何連到 Google 非常慢,但是到 Cloudflare 很快。(大概是因為 Cloudflare 的 edge 比較多?)

為了想要看存在 google drive 的電影,找了一下各種解決方案,後來找到這個 https://github.com/maple3142/GDIndex 。架了用了非常滿意。

Cloudflare workers 太強大,讓我一直在思考還可以拿他來幹嘛,其中一個想法是把它當 HTTP proxy server。

調查了一下, HTTP proxy server 運作是基於 CONNECT method, RFC 規定 CONNECT 之後伺服器必須和客戶端指定的上游建立 TCP 連線(不只是 HTTP 哦),然後幫忙轉遞客戶端和上游之間的 TCP 資料流。

這對於 Cloudflare worker 就很麻煩,因為它的 API 沒辦法直接建立 raw TCP socket ,只有 Fetch (HTTP)

所以結論是,不行,沒辦法用 Cloudflare workers 架設基於 HTTP CONNECT 的 proxy。

不過還是可以拿 workers 架設普通的 reverse proxy 。

我在想如果用 workers 架 reverse proxy 會不會可以繞過一些防爬蟲機制,因為畢竟是 cloudflare IP ,正常服務供應商即使做防爬蟲也可能設定 cloudflare IP 為白名單?類似於說網站不想要把來自 Google 的流量封掉因為可能是搜尋引擎的爬蟲?

ClubHouse 到底安不安全?需要先問幾個問題

前幾個禮拜開始, ClubHouse 在台灣蔚為風尚,隨後不久,就有台灣網友發現 ClubHouse 背後使用的音訊串流技術,是來自中國的 Agora (聲網)公司,引發一波對 ClubHouse 的資安疑慮。網友並提到,聲網公司的其中一個產品,可以對中文音頻內容進行即時偵測和審查,雖然並無證據指出 ClubHouse 有使用這個言論審查的產品,但確定的是 ClubHouse 有使用聲網的其中一個服務(至少根據媒體報導),因此略微有言論審查和監控的疑慮。

幾天之後,有台灣資訊技術圈人士分享從聲網 CTO 聽到的 ClubHouse 技術細節。也有人把 app 拆開看一下裡面有包含什麼元件。這些技術資料雖然並沒有不準確,但若要回答「ClubHouse 安不安全?」這個問題,單看這些技術資料是不夠的。

如何判斷一個應用程式安不安全?

跟大部分專業領域的問題一樣,若要認真回答這個問題,要先反問:「你對安全的定義為何?」這時候就會開始收到各種答案(以 ClubHouse 為例):

  1. 安全就是這個應用程式不會偷我的個資
  2. 安全就是怪人不能隨便進來我的 ClubHouse 房間
  3. 安全就是我不會因為在 ClubHouse 的發言就被查水錶

你應該已經猜到了,以上這些回答都還是很不精確、漏洞百出,可以再接著問下去:

  1. 何謂偷?何謂個資?
  2. 怪人的定義為何?
  3. 查水錶的定義為何?

這樣會沒完沒了,而且即使有問完這些問題的一天,從資安專業的角度看來這些資訊還是非常褊狹,會有各種發問者沒有考慮到的狀況,難以涵蓋「安全」的各種層面。所以通常在討論一個應用程式(或是一個線上服務、一個硬體產品等等)安不安全的時候,我們一次只能在特定範圍和情境下討論安全。如果不限定情境地去討論安全,那是沒有意義的,舉例來說,位在美國的美國公民和位在中國的中國公民,資安上要考慮的事情就差很多。

資訊安全領域中,面對此問題,通常會先進行威脅建模。也就是透過一個預先指定好的框架,去系統性的分析資訊安全的考量(甚至是人身安全可能也可以這樣分析)。威脅建模若要複雜起來可以很複雜,也有各種方法可以去輔助這個釐清的流程,但如果以最簡單的方式出發,其實只需要思考這幾個問題

  1. 我要保護什麼?
  2. 我想保護它免於誰的攻擊?
  3. 如果保護失敗了,後果是什麼?有多糟?
  4. 這攻擊發生的機率有多大?
  5. 我願意花多少心力去避免攻擊一旦成功的後果?

另外需注意到,以上這些問題,很多都牽涉「我」。這些問題很可能對於每個人來說答案都不一樣。如果把「我」這個考慮的範圍太過放大,一次考慮太多人,就會發生因為各種差異而難以討論的問題。

手機應用程式的通病

現今很多網路服務和應用程式都是使用免費來吸引使用者,然後再收集使用者有價值的個人資料來牟利,因此形成幾個大部分人應該都會在意的問題。但對大部分人和應用程式來說,資安問題通常也不會僅止於此

我隨便舉例幾個現今手機應用程式常見的問題:

  1. 收集裝置識別碼和其他裝置資料來追蹤使用者,做得好的話可以跨平臺追蹤使用者。舉例來說可能可以得知這個使用者在拍賣 App 裡面搜尋的關鍵詞,然後他又去比價網站搜尋了其他關鍵詞,然後又造訪某個新聞網站等等。
  2. 透過使用者同意上傳的通訊錄分析使用者的社交圈,以便進行更好的產品推薦,或是對使用者的社交圈的人進一步行銷產品等等。
  3. 整合各種第三方(應用程式開發者之外的)平臺到應用程式內,讓第三方平臺得以跨應用程式收集使用者資料,等於是這些應用程式讓這些第三方平臺來收集使用者個資。第三方平臺通常包含 Facebook, Google ,所以你在應用程式內的瀏覽紀錄會分享給 Facebook 。
  4. 在後端配合應用程式運行的伺服器安全設定不佳,導致資料外洩。

應用程式資安分析

以上的通病和所有其他的資安問題的實際存在與否,都需要進行分析才能得知。針對應用程式的資安分析通常是去細部地觀察應用程式執行時的行為(動態分析),還有應用程式本身的程式碼設計(靜態分析),統稱為「逆向工程」 (reverse engineering)。

逆向工程的過程通常耗時費力,因為應用程式在開發的時候所包含的所有資訊,一部分在編譯和發佈的時候就會被剔除,因此增加逆向工程師理解程式運行邏輯的難度。

更何況應用程式的資訊安全有多種面向,例如《OWASP Mobile Application Security Verification Standard》裡面就包含了八大項。或是台灣自己的行動應用資安聯盟訂立的標準

因此在短時間內,不太可能收集到完整的證據去指出一個應用程式是否安全。更何況每個人對安全的定義還不一樣。

所以我其實不知道 ClubHouse 到底安不安全,因為研究就還沒有結論。

妄下結論

現階段(2021/2/14)的資料並不能對 ClubHouse 的安全性蓋棺論定。現階段我們能做的,是就已公開的資料去評估可信度和他對我們個人資訊安全的影響。換句話說,我並不認為現階段的資料足以支持讓資安專家作出通用的建議,但如果個人硬要去考慮到底要不要用它,可以從現有的資料中就個人的狀況去評估(進行威脅建模)。

這幾年台灣很常見的狀況(網友、媒體、政府),就是把這些初步研究的資料,拿來當作是完整的證據,再下一個沒有道理的結論。舉例來說,應該有很多人聽過「抖音是中國來的軟體,資安有問題,不要用」這個說法,它其實漏洞百出:

  1. 中國來的是指他的開發人員是中國人?是指中國境內還是全世界不特定地點的中國國籍者?還是說他的公司註冊於中國?還是公司的投資者是中國人?
  2. 中國來的軟體資安一定有問題?
  3. 資安有問題的軟體一定不能用?

這些問題,應該如此思考:

  1. 查查維基百科就會發現抖音和 TikTok 是不同的軟體、也是不互通的平台,兩個都同屬一家公司 ByteDance ,ByteDance 總部位於中國等等。
  2. 基於 1 得知的資訊,納入威脅建模的考慮。比如說: ByteDance 的主要開發和應用團隊位於中國,基於中國的法律環境(如國家安全法),中國政府應有法律上的權力去取得 ByteDance 旗下平台的用戶資料。而我不想要讓中國政府有機會蒐集關於我的資料,因此我不用這個 app。
  3. 威脅建模也可能會導出其他結論,比如說有人可能長住中國,已經在當地另外買了手機和門號,新手機的資料和舊手機的資料不互通,所以即使 ByteDance 配合中國政府交出用戶資料他也只能收集到新手機的部分,因此是可接受的風險,並且抖音可能提供了重要的社交功能,因此總結可接受的風險和重要生活功能,結論是可以用。

ClubHouse 現在也是類似,只有證據指出 ClubHouse 使用了 Agora 的服務,而 Agora 是一間中國公司,除此之外都是未經證實的說法。目前只能就這少少的資訊去考慮要不要用 ClubHouse 而已。

如果是一般民眾對於資安不知道該如何思考就算了,偏偏台灣政府裡面也有不少人也是使用這種無腦態度做決策。比如說「台積電是護國神山,新的數位晶片身份證就是採用了台積電製造的晶片,因此絕對安全」,這說法實在跟「抖音是中國來的軟體,資安有問題,不要用」一樣無腦。對於涉及資訊安全的公共決策,應該是要基於務實的資安技術分析、威脅建模、政策研究、成本效益分析等等,而不是用上面一句話做完結論。

2020 年 4 月關於 Zoom 資安的討論也是這樣,雖然已有眾多技術證據指出 Zoom 的資安漏洞,但教育部僅以一紙簡短公文就突然禁用,只因為「有資安疑慮」就禁用,顯然沒有經過更深一層的考慮,去思考「這些資安漏洞是否真的會影響到教育使用的情境」,實際上即使 Zoom 的加密很弱,但教育情境下會透過 Zoom 傳遞的內容本來似乎就不需要高保密性,在不需要高保密性的狀況下,也應該考量軟體本身的功能和方便性可以為教育情境帶來的好處,還有禁用之後的替代品問題。

對於一個不知道安全性如何的應用程式,我也不知道如何進行威脅建模的話,我可以用嗎?

這個就是個人選擇,有點像新出的未核准的藥物要給你加入實驗來試用,你要不要用?

以資訊安全領域來說,我自己是不會用啦,可以先等等讓別人去當白老鼠,不用這個 app 也不會死。但如果是藥物的話,考量就有可能不一樣了。

如果非用不可的話,我會買另一隻手機、註冊另一個電話號碼來用這個 app。沒錢買第二隻手機怎麼辦?沒有付出就別想要有安全啦。

免費、安全、好用三者難以同時存在,只有少數自由開源軟體是例外。

改變資安文化

台灣偶爾會有媒體把食品送到檢驗機構看看安不安全,我覺得對應用程式也應該要做類似的事情,像上述的行動應用資安聯盟應該有能力做。

廠商應該要更清楚地說明他們收集的個資、所做的安全防護、盈利模式,甚至是資安稽核報告。

使用者應該貨比三家,比較產品的功能之外,也比較產品的隱私和安全性,還有隱私政策和使用條款,而且不要只相信廠商講的,也要看獨立的資安研究。並且更主動地拒絕使用標示不清的產品。

政府主管機關應該要是基於專業的研究成果來做決策,而不是在事實不明朗的狀況下就以自己的偏好做決策,還沾沾自喜覺得超前部署。主管機關(甚至消費者保護機構也是)也應該要投注資源鼓勵更多研究。

更新

後來才看到,Stanford Internet Observatory 2/12 發佈了一篇談 ClubHouse 資安的文章,額外確認了幾項技術事實。不過仍有眾多關鍵問題尚未解答,例如:

  1. ClubHouse 傳送語音時是否有經過加密?若有,它使用的加密法是否安全?
  2. ClubHouse 是否、如何收集使用者和裝置的資料,這些資料收集侵犯隱私的程度有多大?
  3. ClubHouse 聊天室的音訊資料是否儲存在中國境內的伺服器?
  4. ClubHouse 的使用者認證機制為何?是否安全?

這些問題還有待更多研究投入去解答。

更新二

Linux 桌面調校筆記

這篇只是筆記看到的有趣東西,大部分我都還沒試過。

CPU

硬碟

記憶體

《在 Linux 桌面上擠出更多記憶體的各種方法、對 SWAP 常見的誤解》

Reverse engineering Cordova apps

Cordova allows you to develop cross-platform mobile apps using web technologies. Traditional way of decompiling Android apps using tools like jadx wouldn’t give you much useful information when dealing with Cordova apps, since most of the logic and interface is implemented in HTML and Javascript.

In theory web apps should be much easier to reverse engineer because there’s technically no “compiling" process, more information is preserved from the original source code. Unless the developer uses an obfuscater, the original program symbols (function names, variable names, etc) are preserved in the final app package. And, because they’re just web technologies, we should be able to just debug them using modern browsers’ amazing debugging tools.

In practice, we need a way to extract the web app part out before we can do anything with it. This doesn’t seem to be a common operation so google doesn’t give you a straight answer, but now I’ve figured it out and find it quite easy.

Note that I have no experience in Android app development, nor Cordova, so there might be more straightforward ways to do things that I don’t know. But so far these methods have served my needs well.

Extracting

Using apktool or jadx we can easily extract the web part of the source code. Cordova apps usually place them under resources/assets/www.

For the app I’m working on, simply opening index.html in a normal browser will lead to it running infinite loop in Javascript.

Running in Browser

To make the app run under normal browser, I took idea from Cordova’s app development tutorial.

First create an empty app project:

cordova create hello com.example.hello HelloWorld
cd hello

Add browser and Android platform. Some plugins will fail to install if android platform wasn’t added:

cordova platform add browser
cordova platform add android

Copy the extracted source files from the app over:

cp -r ~/apk/targetapp/resources/assets/www .

Run in browser:

cordova run browser

This should allow the app to at least start initializing, though if the app uses any Cordova plugins that we haven’t installed yet there will be an error and the initialization would fail. Next step would be to install missing plugins.

Add Missing Plugins

In this step, we need to look at the error messages from the browser console to see what plugins are missing. Below is my example, but each app will use different plugins so the process will vary.

Error: Uncaught ReferenceError: device is not defined

Quick Googling gave me this answer:

cordova plugin add cordova-plugin-device

Add Missing Plugins – a better way

I noticed www/plugins/ contains all plugin files, and the directory names are conveniently the name of the plugin. So I can just use xargs to install all of them:

ls www/plugins/ | xargs cordova plugin add 

This way all plugins included in the app are installed.

Remote Debugging with Chrome

If you connect the phone running the app to you computer and enable Android’s USB debugging, you can use Chrome’s built-in inspector at chrome://inspect to remote debug the app. This only works for apps that declares themselves to be “debuggable" in AndroidManifest.xml. However, if the app is not debuggable, you can still use this Xposed module to make the WebView debuggable without needing to modify the app.

Errors

If an app fails to load in browser, check browser console for error messages. This section notes all error messages I’ve encountered and the solutions.

“Could not find cordova.js script tag. Plugin loading may fail."

I noticed in index.html there was this line:

<script type="text/javascript" src="cordova.93551f4e1f7af4ca1581.js"></script>

And in www/ both cordova.xxx.js and cordova.js exist.

So I simply changed the src in index.html to cordova.js and the app loaded successfully.

Analyzing API Usage

One important part of security auditing apps is to see what system APIs it accesses, under what condition, and what it does with the obtained data.

In Cordova, most system API access require plugins. The app logic in Javascript would call respective plugins’ Javascript API, and in turn call the Java part of the plugin, then from there call system Java APIs.

So to answer the above questions, here’s the high level process that I usually take:

  1. Use jadx to look for Java code that calls interesting system APIs
  2. Note down the Java package name containing the code block of interest, for example: org.apache.cordova.file.FileUtils or com.rohithvaranasi.callnumber.CFCallNumber
  3. Google for these plugins’ documentation on their Javascript API. Using the above plugins as examples, I found:
    1. cordova-plugin-file : https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/
    2. CordovaCallNumberPlugin: https://github.com/rohfosho/CordovaCallNumberPlugin
  4. Read their documentation and look for the global object name encapsulating the plugin’s functions, or the function names of interest. For example, CordovaCallNumberPlugin offers only one function here: window.plugins.CallNumber.callNumber
  5. Go back to the app’s Javascript source code, grep for use of CallNumber.callNumber

TODO: Tweak CORS

If the app wants to send any HTTP request to external servers (other than localhost, most likely due to the app calling API servers), in the browser it will fail from CORS requirements.

I didn’t investigate to fix this because I didn’t need to inspect the server response. But this should be fixable by tweaking the CORS header sent by cordova run browser .