國產github崩了?是防盜鏈啦~

前端私教年年發表於2022-03-29

今天一早開啟微信,就看到國產github——gitee崩了。


Issue列表裡面全是反饋圖片顯示異常,仔細一看,原來是圖床的防盜鏈。

場景復現

之前沒用過gitee,火速去建了一個賬號試驗一下。

我在我的gitee中上傳一張圖片,在gitee本站裡面顯示是正常的。

右鍵複製這張圖片的地址,放到一個第三方的線上編輯器中,發現圖片變成gitee的logo了

什麼是防盜鏈

防盜鏈不是防止一根鏈條,正確的停頓應該是防·盜鏈——防止其他網站盜用我的連結。

我把圖片上傳到gitee的伺服器,得到了圖片的連結,然後拿著這個連結在第三方編輯器中使用,這就是在“盜用”——因為這張圖片佔用了gitee的伺服器資源,卻為第三方編輯器工作,gitee得不到好處,還得多花錢。

如何實現防盜鏈

要實現防盜鏈,就需要知道圖片的請求是從哪裡發出的。可以實現這一功能的有請求頭中的originrefererorigin只有在XHR請求中才會帶上,所以圖片資源只能藉助referer。其實gitee也確實是這麼做的。

通過判斷請求的referer,如果請求來源不是本站就返回302,重定向到gitee的logo上,最後在第三方網站引用存在gitee的資源就全變成它的logo了。

可以在開發者工具中看到第三方網站請求gitee圖片的流程:

  1. 首先請求正常的圖片,但是沒有返回200,而是302重定向,其中響應頭中的location就是要重定向去向的地址;
  2. 接著瀏覽器會自動請求這個location,並用這個返回結果代替第一次請求的返回內容;

最後,我們的圖片在第三方網站就變成gitee的logo了。

如何破解防盜鏈

想讓gitee不知道我在盜用,就不能讓他發現請求的來源是第三方,只要把referer藏起來就好,可以在終端嘗試這段程式碼:

curl 'https://images.gitee.com/uploads/images/2022/0326/155444_dc9923a4_10659337.jpeg' \
 -o noReferer.jpg 

這段?程式碼的意思是請求這張jpg圖片資源,把返回結果以noReferer.jpg這個名稱儲存在當前目錄下,並且沒有帶上referer,測試結果是圖片正常儲存下來了。

就像加上了gitee本站的referer一樣可以正常請求?:

curl 'https://images.gitee.com/uploads/images/2022/0326/155444_dc9923a4_10659337.jpeg' \
 -H 'referer: https://gitee.com' \
 -o fromGitee.jpg

而在第三方網站請求的效果就像這段?程式碼

curl 'https://images.gitee.com/uploads/images/2022/0326/155444_dc9923a4_10659337.jpeg' \
  -H 'referer: https://editor.mdnice.com/' \
  -o otherReferer.png

帶上了第三方網站的標識https://editor.mdnice.com最終無法正常下載。

gitee做的不夠完善嗎

測試完上面的三段程式碼,不知道你會不會疑惑,gitee為什麼不把“請求來源不能是第三方網站”的策略改成“請求來源必須是本站點”呢?換句話說,控制referer不能為空,只要是空就重定向。

因為在瀏覽器的位址列中直接輸入這個圖片的url,然後回車,發起的請求是沒有referer欄位的,在這種場景下如果還是返回gitee的logo,就顯得不太合理了。

圖片的url:https://images.gitee.com/uplo...

圖片看不到了,現在怎麼辦

如果你的個人搭建的部落格裡面用了很多存在gitee的圖片,你可以在html的head部分加上這樣一行

<meta name="referrer" content="no-referrer" />

或者

<img referrer="no-referrer|origin|unsafe-url" src="{item.src}"/>

來阻止請求因帶上站點來源而被重定向成gitee的logo。

如果你是部落格的訪問者,可以藉助一個chrome小外掛ModHeader,把referer給“擦掉”


這樣第三方站點就可以正常訪問啦~

結語

上面提到的解決方式只是開個玩笑,臨時恢復使用可以。但還是要慢慢把圖片遷移到自己的伺服器才最可靠。

如果覺得這篇文章對你有幫助,給我點個讚唄~這對我很重要

點個在看更好!

相關文章