淺析HTTP的Referer含義理解、Referer作用(記錄訪問來源、防盜鏈、防止惡意請求)、Referrer Policy引用策略的9個值及設置用法、什么情況會導致空Referer


  HTTP 請求的頭信息里面,Referer 是一個常見字段,提供訪問來源的信息。很多開發者知道這個字段,但是說不清它的具體細節。本文詳細介紹該字段。

一、Referer 的含義

  現實生活中,購買服務或加入會員的時候,往往要求提供信息:"你從哪里知道了我們?",這叫做引薦人(referrer),誰引薦了你?對於公司來說,這是很有用的信息。互聯網也是一樣,你不會無緣無故訪問一個網頁,總是有人告訴你,可以去那里看看。服務器也想知道,你的"引薦人"是誰?

  HTTP 協議在請求(request)的頭信息里面,設計了一個 Referer 字段,給出"引薦網頁"的 URL。

  Referer  是  HTTP  請求header 的一部分,當瀏覽器向服務器發送請求的時候,頭信息里有包含  Referer  。比如我在www.google.com 里有一個www.baidu.com 鏈接,那么點擊這個www.baidu.com ,它的header 信息里就有:Referer=http://www.google.com,由此可以看出來:它就是表示一個來源。

  比如我從百度搜索關鍵字,然后跳轉到我們網站,那么其 Referer 就是百度的搜索鏈接,百度鏈接比較長,帶上了關鍵字之類的,如果是谷歌的話,就只有谷歌的網址,沒有關鍵字那些。

  這個字段是可選的。客戶端發送請求的時候,可以自主決定是否加上該字段。

  需要注意的是,這個字段的拼寫是錯的。Referer 的正確拼寫是 Referrer,但是寫入標准的時候,不知為何,沒人發現少了一個字母 r。標准定案以后,只能將錯就錯,所有頭信息的該字段都一律錯誤拼寫成 Referer

二、Referer 的常見作用

  Referer 字段實際上告訴了服務器,用戶在訪問當前資源之前的位置,這往往可以用來用戶跟蹤。

1、用戶行為日志記錄訪問來源:這個就不多說了。

2、另一個典型的應用是:防盜鏈

  比如有些網站不允許圖片外鏈,只有自家的網站才能顯示圖片,外部網站加載圖片就會報錯。它的實現就是基於Referer字段,如果該字段的網址是自家網址,就放行。

  剛剛前面有提到一個小 demo,我在www.google.com里有一個www.baidu.com鏈接,那么點擊這個www.baidu.com,它的header信息里就有:Referer=http://www.google.com,那么可以利用這個來防止盜鏈了,比如我只允許我自己的網站訪問我自己的圖片服務器,那我的域名是www.google.com,那么圖片服務器每次取到Referer來判斷一下是不是我自己的域名www.google.com,如果是就繼續訪問,不是就攔截。這是不是就達到防盜鏈的效果了呢。

  如何處理:將http請求發給服務器后,如果服務器要求必須是某個地址或者某幾個地址才能訪問,而你發送的referer不符合他的要求,就會攔截或者跳轉到他要求的地址,然后再通過這個地址進行訪問。

  對於某些惡意用戶,也可能偽造Referer來獲得某些權限,在設計網站時要考慮到這個問題。比如做電子商務網站的安全,在提交信用卡等重要信息的頁面用 referer 來判斷上一頁是不是自己的網站,如果不是,可能是黑客用自己寫的一個表單來提交,為了能跳過你上一頁里的 javascript 的驗證等目的。但是注意不要把Rerferer用在身份驗證或者其他非常重要的檢查上,因為Rerferer非常容易在客戶端被改變。

3、防止惡意請求

  比如靜態請求是.html結尾的,動態請求是.shtml,那么所有的*.shtml請求,必須 Referer為我自己的網站才可以訪問,這就是Referer的作用。

4、由於涉及隱私,很多時候不適合發送Referer字段。

  這里舉兩個例子,都不適合暴露 URL。一個是功能 URL,即有的 URL 不要登錄,可以訪問,就能直接完成密碼重置、郵件退訂等功能。另一個是內網 URL,不希望外部用戶知道內網有這樣的地址。Referer字段很可能把這些 URL 暴露出去。

  此外,還有一種特殊情況,需要定制Referer字段。比如社交網站上,用戶在對話中提到某個網址。這時,不希望暴露用戶所在的原始網址,但是可以暴露社交網站的域名,讓對方知道,是我貢獻了你的流量。

(1)隱私:社交網站一般都會有用戶個人頁面,這些頁面中用戶都有可能添加一些外網的鏈接,而社交網站有可能不希望在用戶點擊了這些鏈接的時候,泄露用戶頁面的 URL ,因為這些 URL 中可能包含一些敏感信息。當然,有些社交網站可能只想在 referer 中提供一個 hostname,而不是完整的 URL 信息。

(2)安全:有些使用了 https 的網站,可能在 URL 中使用一個參數(sid 等)來作為用戶身份憑證,而又需要引入其他 https 網站的資源,這種情況下,網站肯定不希望泄露用戶的身份憑證信息。

三、rel 屬性

  由於上一節的原因,瀏覽器提供一系列手段,允許改變默認的 Referer 行為。對於用戶來說,可以改變瀏覽器本身的全局設置,也可以安裝瀏覽器擴展。這里就不詳細介紹了。

  對於開發者來說,rel="noreferrer" 屬性是最簡單的一種方法。<a><area><form>三個標簽可以使用這個屬性,一旦使用,該元素就不會發送Referer字段。

<a href="..." rel="noreferrer" target="_blank">xxx</a>

  上面鏈接點擊產生的 HTTP 請求,不會帶有Referer字段。注意,rel="noreferrer" 采用的是正確的拼寫

四、Referrer Policy 的值及用法

1、什么是引用策略(Referrer Policy)

  引用策略就是從一個文檔發出請求時,是否在請求頭部定義 Referrer 的設置。

  目前很多網站的防盜鏈機制都是用頭部定義 Referrer 來判斷是否是盜鏈。其實這個很容易破解,自己在請求時加上 Referrer 頭部就行。

  在哪些情況下會設置引用頭呢?一般來說,加載一個 HTML 頁面之后,本 HTML 頁面里的 JavaScript 文件,CSS 文件,畫面文件都會設置 Referrer。然后,點擊這個 HTML 頁面里的鏈接,跳轉其它畫面時,也會設置 Referrer。

2、Referrer Policy 的 9 個取值:

  rel 屬性只能定制單個元素的Referer行為,而且選擇比較少,只能發送或不發送。W3C 為此制定了更強大的 Referrer Policy。Referrer Policy 可以設定9個值。

(1)空字符串  -  默認值:一般瀏覽器的默認值是 no-referrer-when-downgrade

(2)no-referrer  -  所有請求不發送 referrer。

(3)no-referrer-when-downgrade:當請求安全級別下降時不發送 referrer。目前,只有一種情況會發生安全級別下降,即從 HTTPS 到 HTTP。HTTPS 到 HTTP 的資源引用和鏈接跳轉都不會發送 referrer。

(4)same-origin:對於同源的鏈接和引用,會發送referrer,其他的不會。同源的意思是指同一個域名且同一協議。如果設置成 same-origin,那么 aaa.com 引用 bbb.com 的資源,不會發送 referrer。子域名也不是同一個域名,aaa.com 引用 test.aaa.com 的資源,不會發送 referrer。

(5)origin:會發送 referrer,但只會發送源信息。源信息包括訪問協議和域名。

(6)strict-origin:這個相當於 origin 和 no-referrer-when-downgrade 的 AND 合體。即在安全級別下降時不發送 referrer;安全級別未下降時發送源信息。

  注意:這個是新加的標准,有些瀏覽器可能還不支持。

(7)origin-when-cross-origin:這個相當於 origin 和 same-origin 的 OR 合體。同源的鏈接和引用,會發送完全的 referrer 信息;但非同源鏈接和引用時,只發送源信息。

(8)strict-origin-when-cross-origin:這個比較復雜,同源的鏈接和引用,會發送 referrer。安全級別下降時不發送 referrer。其它情況下發送源信息。

  注意:這個是新加的標准,有些瀏覽器可能還不支持。

(9)unsafe-url:無論是否發生協議降級,無論是本站鏈接還是站外鏈接,統統都發送 Referrer 信息。正如其名,這是最寬松而最不安全的策略。

3、Referrer Policy 的設置方法:

(1)HTTP 頭信息:服務器發送網頁的時候,通過 http 響應頭中的 Referrer-Policy 字段告訴瀏覽器

Content-Security-Policy: referrer no-referrer|no-referrer-when-downgrade|origin|origin-when-cross-origin|unsafe-url;

(2)<meta> 標簽:也可以使用<meta>標簽,在網頁頭部設置。

<meta name="referrer" content="no-referrer|no-referrer-when-downgrade|origin|origin-when-crossorigin|unsafe-url">

(3)referrerpolicy 屬性:<a><area><img><iframe><link>標簽,可以設置referrerpolicy 屬性。

<a href="..." referrerpolicy="origin" target="_blank">xxx</a>

4、退出頁面重定向

  還有一種比較老式的技巧,但是非常有效,可以隱藏掉原始網址,谷歌和 Facebook 都在使用這種方法。

  鏈接的時候,不要直接跳轉,而是通過一個重定向網址,就像下面這樣。

<a  href="/exit.php?url=http%3A%2F%2Fexample.com">Example.com</a>

  上面網址中,先跳轉到/exit.php,然后再跳轉到目標網址。這時,Referer字段就不會包含原始網址。

五、空Referer是怎么回事

  空Referer是指Referer頭部的內容為空,或者,一個HTTP 請求頭中根本不包含Referer,那么什么時候HTTP請求會不包含Referer字段呢?

  根據Referer的定義,它的作用是指示一個請求是從哪里鏈接過來,那么當一個請求並不是由鏈接觸發產生的,那么自然也就不需要指定這個請求的鏈接來源。

  比如,直接在瀏覽器的地址欄中輸入一個資源的URL地址,那么這種請求是不會包含Referer字段的,因為這是一個“憑空產生”的HTTP請求,並不是從一個地方鏈接過去的。

  那么在防盜鏈設置中,允許空Referer和不允許空Referer有什么區別?

  允許Referer為空,意味着你允許比如瀏覽器直接訪問,就是空。

  拒絕空的 Referer ,比如我的www.sojson.com的靜態資源都是拒絕空的Referer 的,那么當我訪問我的一個圖片時,就訪問不了,直接報 403 拒絕訪問。

  最后我們了解一下哪些情況下無法獲得上一頁 referrer 信息:

(1)直接在瀏覽器地址欄中輸入地址;

(2)使用 location.reload() 刷新( location.href 或者 location.replace() 刷新有信息);

(3)在微信對話框中,點擊鏈接進入微信自身的瀏覽器;

(4)掃碼進入QQ或者微信的瀏覽器;

(5)直接新窗口打開一個頁面;

(6)a標簽設置 rel="noreferrer"

(7)meta標簽來控制不讓瀏覽器發送referer;例如:<meta content="never" name="referrer">


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM