重寫 Ptt 上的 Imgur Userscript 解決圖片出不來的問題

前幾個禮拜 Imgur 決定擋掉 Ptt 的網頁版,所以 Ptt 網頁版上會發現 Imgur 的圖都不見了:「[問題] 突然imgur的貼圖無法顯示」。

這是因為 Imgur 用 Referer 擋了 Ptt 的關係,後來 Ptt 官方在 8/15 後有針對 https://i.gslin.com/imgur/ 的圖片改用 https://cache.ptt.cc/ 過一層,不過 https://imgur.com/ 的就沒圖了。

這邊可以參考 Certificate Transparency 的「crt.sh | cache.ptt.cc」記錄,以及台大對於 Ptt 的流量的記錄 (出自「PTT 流量分析」這邊):

除了 Ptt 官方的解法外,另外可以自己寫 userscript,用 Referrer-Policy 繞過 (需要比較新版的瀏覽器,不過目前的瀏覽氣應該都夠新),看了一下本來的 ptt-imgur-cleaner-gm,發現要整個打掉改寫,索性就開一個新的專案變成 imgur-links-rewriting-on-ptt

這個版本的特色:

  • 加上對 https://imgur.com/a/ (album) 的支援,可以顯示第一張圖。
  • WebP 的版本,下載速度應該會快一些。
  • 偏好都是用大圖 (原始大小的圖片)。
  • 把本來走 https://cache.ptt.cc/ 的版本換回直接走 https://i.gslin.com/imgur/,就不用透過 TANet 或是台大的出國頻寬了。

程式碼不長 (參考「imgur-links-rewriting-on-ptt.user.js」這邊),主要是練手... 沒事就寫一下 userscript 可以維持對於 JavaScript 的基本熟悉度。

Chrome 72+ (目前在 Beta 的版本) 對延伸套件的影響

我的桌機平常都是跑 beta channel 的 Chrome,所以前陣子已經升級到 72,然後發現兩個問題:

從 dev console 可以看到問題都是 Referer 沒被送出,導致有檢查 Referer 的網站拒絕存取,後來在「chrome.webRequest」這邊發現是 Chrome 72+ 改了規則,裡面提到了:

Starting from Chrome 72, the following request headers are not provided and cannot be modified or removed without specifying 'extraHeaders' in opt_extraInfoSpec:

Accept-Language
Accept-Encoding
Referer
Cookie

Starting from Chrome 72, the Set-Cookie response header is not provided and cannot be modified or removed without specifying 'extraHeaders' in opt_extraInfoSpec.

不確定這個設計的目的是什麼,但反正已經中獎了,總是得回報給各 extension 的維護者讓他們修正 (用 beta channel 的重要任務之一?)。

所以就先去 Tampermonkey 開 ticket,也很迅速的在 beta 版修正了 (所以只能先改裝 beta 版):「GM_xmlhttpRequest unable to set referer in Chrome 72+ #629」。

另外跟 Referer Control 的開發者回報這個問題,也修正出新版上架了,更新就生效了:「refererControlDisqus.html」。

目前看起來還有「Spoofs Lang」得修,不過這個軟體好久沒更新了,不知道有沒有機會...

Firefox 對 HTTPS 網站中 "Referer" 的保護

Firefox 從 59 之後,在開啟 Private Browsing 的情況下,不會送出完整的 Referer:「Preventing data leaks by stripping path information in HTTP Referrers」。

這篇吸引到我的是 EFF 的研究員發現的事情:

EFF researchers discovered this leak of personal health data from healthcare.gov to DoubleClick.

其中 EFF 研究員的文章是「HealthCare.gov Sends Personal Data to Dozens of Tracking Websites」這篇。

更好的作法應該是平常就完全阻擋,像是 Firefox 可以用 Referrer Control 設定,或是 Chrome 裡用 Referer Control 設定。

HTTPS 因為安全性而不能使用 Referrer 的問題

Nuzzel 上看到老文章在討論 HTTPS 環境下因為安全性考量,而不能帶出 Referrer 的問題:「Where did all the HTTP referrers go?」。

原文中「Fixing Referrers in HTTPS: The Meta Referrer」這邊就有提到 HTML5 meta referrer,也就是 W3C 的「Referrer Policy」,問題是到現在還是 Draft 啊...

也因為過了三年,其實 draft 裡面多了不少參數可以用:

  • neverno-referrer 表示不傳。
  • origin 表示只傳 protocol + host 的部份,後面 path 的部份不要傳。
  • defaultno-referrer-when-downgrade 表示當 downgrade 時 (HTTP request 的部份) 不要傳。
  • origin-when-cross-origin 表示當跨站時用 origin 的邏輯,但本站還是用完整的路徑。
  • always 或是 unsafe-url 則是永遠都傳。

其中刪節號表示 W3C 不建議再使用,應該用後者比較新的。

不過因為在 Can I use 上面可以看到 Microsoft Edge 只支援舊的關鍵字 (也就是刪節號的那些),所以還是可以考慮先用舊的關鍵字,讓 Microsoft Edge 也可以被保護到:「Referrer Policy」。

Google Chrome Extension 內攔截所有的 url request...

之前寫了一個處理 Referer header 的 extension,使用 chrome.experimental.webRequest.onBeforeSendHeaders.addListener 攔截所有的 url 然後處理 Referer header。

之前只需要在 manifest.json 裡面加上 experimental 就可以使用,但是前陣子發現失效。剛剛在「onBeforeSendHeaders listeners aren't triggering」這個 issue 裡面找到解法:現在需要多加上 <all_urls> 這組權限。