簡介
內容嗅探,也被稱為媒體型別嗅探或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有兩中型別,分別是discrete 和multipart。
離散型別是代表單一檔案或媒介的型別,如單一文字或音樂檔案,或單一視訊。
多部分型別是指由多個元件組成的檔案,每個元件都有自己獨立的MIME型別;或者,指封裝在一個事務中一起傳送的多個檔案。例如,電子郵件中多個附件就是一種多部分MIME型別。
我們看下常見的discrete型別:
- application, 比如:
application/octet-stream
,application/pdf
,application/pkcs8
和application/zip
等。 - audioList, 比如:
audio/mpeg
,audio/vorbis
。 - font, 比如:
font/woff
,font/ttf
和font/otf
。 - image,比如:
image/jpeg
,image/png
和image/svg+xml
。 - model, 比如:
model/3mf
和model/vml
。 - text,比如:
text/plain
,text/csv
和text/html
. - video,比如:
video/mp4
。
常見的Multipart型別如下:
- message,比如:
message/rfc822
和message/partial
。 - 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/
最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!