密碼學系列之:內容嗅探

flydean發表於2021-03-10

簡介

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

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

MIME types

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有兩中型別,分別是discretemultipart

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

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

我們看下常見的discrete型別:

  1. application, 比如:application/octet-streamapplication/pdfapplication/pkcs8application/zip等。
  2. audioList, 比如:audio/mpegaudio/vorbis
  3. font, 比如:font/wofffont/ttffont/otf
  4. image,比如:image/jpegimage/pngimage/svg+xml
  5. model, 比如:model/3mfmodel/vml
  6. text,比如:text/plain, text/csvtext/html.
  7. video,比如:video/mp4

常見的Multipart型別如下:

  1. message,比如:message/rfc822message/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/

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

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

相關文章