天天看點

密碼學系列之:内容嗅探

目錄

  • 簡介
  • MIME types
  • 浏覽器嗅探
  • 用戶端嗅探

内容嗅探,也被稱為媒體類型嗅探或MIME嗅探,是檢查一個位元組流的内容,試圖推斷其中資料的檔案格式的做法。内容嗅探通常用在媒體類型沒有被準确指定的情況,用于補償中繼資料資訊。

本文将會講解内容嗅探的常用場景和可能出現的問題。

MIME的全稱是Multipurpose Internet Mail Extensions,多用途網際網路郵件擴充。它是一種标準,它表明了文檔、檔案或各種位元組的性質和格式。它是在IETF的RFC 6838中定義的。網際網路編号配置設定機構(IANA)負責定義所有官方的MIME類型。

MIME的結構包含兩部分,分别是type和subtype,他們以 / 來進行分割:

type/subtype
           

類型代表資料類型所屬的一般類别,如視訊或文本。子類型确定MIME類型所代表的指定類型的确切資料種類。例如,對于 MIME 類型的文本,子類型可能是 plain(純文字)、html(HTML 源代碼)或月曆(對于 iCalendar/.ics)檔案。

每種類型都有它自己的一套可能的子類型, 一個MIME類型必須包含一個類型和一個子類型。

還可以在後面加上額外的參數:

type/subtype;parameter=value
           

例如,對于主類型是text的任何MIME類型,可選的charset參數可以用來指定資料中字元的字元集。如果沒有指定字元集,預設為ASCII (US-ASCII),除非被使用者代理的設定覆寫。要指定UTF-8文本檔案,則使用MIME類型text/plain;charset=UTF-8。

MIME類型不區分大小寫,但傳統上用小寫,但參數值除外,因為參數值的大小寫可能有或沒有特定的意義。

MIME有兩中類型,分别是discrete 和multipart。

離散類型是代表單一檔案或媒介的類型,如單一文本或音樂檔案,或單一視訊。

多部分類型是指由多個元件組成的檔案,每個元件都有自己獨立的MIME類型;或者,指封裝在一個事務中一起發送的多個檔案。例如,電子郵件中多個附件就是一種多部分MIME類型。

我們看下常見的discrete類型:

  1. application, 比如:

    application/octet-stream

    application/pdf

    application/pkcs8

    application/zip

    等。
  2. audioList, 比如:

    audio/mpeg

    audio/vorbis

  3. font, 比如:

    font/woff

    font/ttf

    font/otf

  4. image,比如:

    image/jpeg

    image/png

    image/svg+xml

  5. model, 比如:

    model/3mf

    model/vml

  6. text,比如:

    text/plain

    ,

    text/csv

    text/html

    .
  7. video,比如:

    video/mp4

常見的Multipart類型如下:

  1. message,比如:

    message/rfc822

    message/partial

  2. multipartList, 比如:multipart/form-data 和

    multipart/byteranges

因為浏覽器使用MIME類型,而不是檔案擴充名來決定如何處理一個URL,是以Web伺服器在響應的Content-Type頭中發送正确的MIME類型非常重要。如果沒有正确配置,浏覽器很可能會誤解檔案的内容,網站将無法正常運作,下載下傳的檔案也可能會被錯誤處理。

為了解決這個問題,或者說是更好的使用者體驗,很多浏覽器會進行MIME内容嗅探,也就是通過解析檔案的内容,來猜測MIME類型的格式。

不同的浏覽器處理MIME嗅探的方式是不一樣的。但是他們都可能會産生嚴重的安全漏洞,因為有些MIME類型是可執行類型的,惡意攻擊者可以通過混淆MIME嗅探算法,進而使攻擊者可以進行網站營運者或使用者都沒有預料到的操作,如跨站腳本攻擊。

如果不想浏覽器端進行嗅探,可以在服務端的響應中設定

X-Content-Type-Options

頭,比如:

X-Content-Type-Options: nosniff
           

這個頭最早是在IE 8中支援的,不過現在所有的浏覽器基本都支援這個head類型了。

我們通常需要在JS中判斷浏覽器是否是IE浏覽器,然後做響應的處理:

var isIEBrowser = false;
if (window.ActiveXObject) {
    isIEBrowser = true;
}

// Or, shorter:
var isIE = (window.ActiveXObject !== undefined);
           

上面的例子就是非常簡單的用戶端嗅探,通過判斷window是否有ActiveXObject 這個屬性來确定這個浏覽器是否是IE浏覽器。

本文已收錄于 http://www.flydean.com/content-sniffing/

最通俗的解讀,最深刻的幹貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!

歡迎關注我的公衆号:「程式那些事」,懂技術,更懂你!