非標(biāo)準(zhǔn) HTTP 報(bào)頭

各瀏覽器對于以下各種非標(biāo)準(zhǔn) HTTP 報(bào)頭的兼容情況可以參考 Can I Use 站點(diǎn)上的相關(guān)內(nèi)容。

請求頭

DNT

請求某個(gè)網(wǎng)頁應(yīng)用程序停止跟蹤某個(gè)用戶。在 Firefox 瀏覽器中,相當(dāng)于 X-Do-Not-Track 協(xié)議頭字段(自 Firefox 4.0 測試(Beta)11 版開始支持)。 Safari 和 IE 9 也支持這個(gè)字段。

DNT: 1 (啟用)
DNT: 0 (禁用)

注:目前 DNT 在 W3C 還未正式成為標(biāo)準(zhǔn),參考:Tracking Preference Expression (DNT)

X-Forwarded-For

一個(gè)事實(shí)標(biāo)準(zhǔn),用于標(biāo)識某個(gè)通過超文本傳輸協(xié)議代理或負(fù)載均衡連接到某個(gè)網(wǎng)頁服務(wù)器的客戶端的原始互聯(lián)網(wǎng)地址。

X-Forwarded-For: client1, proxy1, proxy2
X-Forwarded-For: 129.78.138.66, 129.78.64.10

在 Java Servlet 中獲取客戶端 IP 地址的參考代碼:

import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ServletUtils {

    private static final Logger log = LoggerFactory.getLogger( ServletUtils.class );

    private static final String[] PROXY_REMOTE_IP_ADDRESS;

    static {

        // read2Array 將文件中的內(nèi)容讀出作為數(shù)組,
        // 每個(gè)數(shù)組中的元素中文件中的一行,
        // 若文件不存在時(shí)返回空數(shù)組
        String[] proxyRemoteHeaders = read2Array( Thread.currentThread().getContextClassLoader() , "remote-ip-headers" );

        if ( proxyRemoteHeaders.length == 0 ) {
            proxyRemoteHeaders = read2Array( ServletUtils.class , "remote-ip-headers-default" );
        }

        PROXY_REMOTE_IP_ADDRESS = proxyRemoteHeaders;
        log.info( "Remote address headers: {}" , Arrays.toString( PROXY_REMOTE_IP_ADDRESS ) );
    }

    /**
     * 獲取請求的客戶端的 IP 地址。若應(yīng)用服務(wù)器前端配有反向代理的 Web 服務(wù)器,
     * 需要在 Web 服務(wù)器中將客戶端原始請求的 IP 地址加入到 HTTP header 中。
     *
     * Web 服務(wù)器反向代理中用于存放客戶端原始 IP 地址的 Http header 名字,
     * 默認(rèn)值為根據(jù)優(yōu)先級為 "X-Forwarded-For" 和 "X-Real-IP",
     * 若有需要使用其他的 HTTP header,需要在 classpath 的 remote-ip-headers
     * 文件中添加所需要的 HTTP header 名字,根據(jù)優(yōu)先級依次在該文件中增加數(shù)據(jù),
     * 格式為每行一個(gè) headers 名稱。
     *
     * @param request HTTP 請求
     * @return  遠(yuǎn)程客戶端的 IP 地址
     */
    public static String getRemoteIp(HttpServletRequest request) {
        for ( int i = 0; i < PROXY_REMOTE_IP_ADDRESS.length; i++ ) {
            String ip = request.getHeader( PROXY_REMOTE_IP_ADDRESS[i] );
            if ( StringUtils.isNotBlank(ip) ) {
                return getRemoteIpFromForward( ip );
            }
        }
        return request.getRemoteAddr();
    }

    /**
     * 從 HTTP Header 中根據(jù)反向代理請求頭的規(guī)范截取客戶端連接 IP 地址。
     * 如果經(jīng)過多次反向代理,在相應(yīng)的請求頭中獲得的是以“,&lt;SP&gt;”
     * 分隔 IP 地址鏈,第一段則為客戶端 IP 地址。
     *
     * @param xforwardIp
     * @return 通過代理服務(wù)器后獲取的客戶端 IP 地址
     */
    private static String getRemoteIpFromForward(String xforwardIp) {
        int commaOffset = xforwardIp.indexOf(',');
        if (commaOffset < 0) {
            return xforwardIp;
        }
        return xforwardIp.substring(0, commaOffset);
    }
}

注:在 RFC 7239 中被 Forwarded 請求頭取代。

X-Forwarded-Host

一個(gè)事實(shí)標(biāo)準(zhǔn),用于請求客戶端原始 Host 的 HTTP 請求頭,由于經(jīng)過反向代理(負(fù)載均衡服務(wù)器)原始的 Host 值可能與實(shí)際值不同。

X-Forwarded-Host: en.wikipedia.org:80
X-Forwarded-Host: en.wikipedia.org

注:在 RFC 7239 中被 Forwarded 請求頭取代。

X-Forwarded-Proto

一個(gè)事實(shí)標(biāo)準(zhǔn),用于標(biāo)識某個(gè)超文本傳輸協(xié)議請求最初所使用的協(xié)議,因?yàn)?,在反向代理(?fù)載均衡)上,即使最初發(fā)往該反向代理的請求類型是安全的超文本傳輸協(xié)議(HTTPS),該反向代理也仍然可能會使用超文本傳輸協(xié)議(HTTP)來與網(wǎng)頁服務(wù)器通信。谷歌客戶端在與谷歌服務(wù)器通信時(shí)會使用該協(xié)議頭的一個(gè)替代形式(X-ProxyUser-Ip)。

X-Forwarded-Proto: https

注:在 RFC 7239 中被 Forwarded 請求頭取代。

X-Http-Method-Override

請求某個(gè)網(wǎng)頁應(yīng)用程序使用該協(xié)議頭字段中指定的方法(一般是 PUT 或 DELETE)來覆蓋掉在請求中所指定的方法(一般是 POST)。當(dāng)某個(gè)瀏覽器或防火墻阻止直接發(fā)送 PUT 或 DELETE 方法時(shí)(注意,這可能是因?yàn)檐浖械哪硞€(gè)漏洞,因而需要修復(fù),也可能是因?yàn)槟硞€(gè)配置選項(xiàng)就是如此要求的,因而不應(yīng)當(dāng)設(shè)法繞過),可使用這種方式。

X-HTTP-Method-Override: DELETE

在開發(fā) REST 風(fēng)格的 Web 服務(wù)時(shí),應(yīng)將 X-Http-Method-Override 考慮至實(shí)現(xiàn)中。在 Spring MVC 中有個(gè)通過 _method 請求參數(shù)實(shí)現(xiàn)的過濾器 HiddenHttpMethodFilter,可以參照這個(gè)過濾器去實(shí)現(xiàn)一個(gè)用于處理 X-Http-Method-Override 請求頭的過濾器。

X-Requested-With

主要用于標(biāo)識 Ajax 及可擴(kuò)展標(biāo)記語言請求。大部分的 JavaScript 框架會發(fā)送這個(gè)字段,且將其值設(shè)置為 XMLHttpRequest。

X-Requested-With: XMLHttpRequest

響應(yīng)頭

Timing-Allow-Origin

參考:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Timing-Allow-Origin

用于指定特定站點(diǎn),以允許其訪問 Resource Timing API 提供的相關(guān)信息,否則這些信息會由于跨源限制將被報(bào)告為零。

Timing-Allow-Origin: *
Timing-Allow-Origin: <origin>[, <origin>]*

Strict-Transport-Security

一種 HSTS(HTTP Strict Transport Security, HTTP 嚴(yán)格傳輸安全)策略,強(qiáng)制客戶端(如瀏覽器)使用 HTTPS 與服務(wù)器創(chuàng)建連接。服務(wù)器開啟 HSTS 的方法是,當(dāng)客戶端通過 HTTPS 發(fā)出請求時(shí),在服務(wù)器返回的超文本傳輸協(xié)議響應(yīng)頭中包含 Strict-Transport-Security 字段。非加密傳輸時(shí)設(shè)置的 HSTS 字段無效。

比如,https://example.com/ 的響應(yīng)頭含有 Strict-Transport-Security: max-age=31536000; includeSubDomains。這意味著兩點(diǎn):

  • 在接下來的一年(即 31536000 秒)中,瀏覽器只要向 example.com 或其子域名發(fā)送 HTTP 請求時(shí),必須采用 HTTPS 來發(fā)起連接。比如,用戶點(diǎn)擊超鏈接或在地址欄輸入 http://www.example.com/,瀏覽器應(yīng)當(dāng)自動將 http 轉(zhuǎn)寫成 https,然后直接向 https://www.example.com/ 發(fā)送請求。
  • 在接下來的一年中,如果 example.com 服務(wù)器發(fā)送的 TLS 證書無效,用戶不能忽略瀏覽器警告繼續(xù)訪問網(wǎng)站。
Strict-Transport-Security: max-age=31536000; includeSubDomains

安全提示:若網(wǎng)站是 HTTPS 時(shí)應(yīng)設(shè)置該響應(yīng)頭,以避免通過 HTTP 發(fā)起請求后在服務(wù)器端進(jìn)行 302 跳轉(zhuǎn)至 HTTPS,這樣存在中間人攻擊潛在威脅,跳轉(zhuǎn)過程可能被惡意網(wǎng)站利用來直接接觸用戶信息,而不是原來的加密信息。更多的信息參考 MDN 中相關(guān)的內(nèi)容。

友情提示:一旦設(shè)置了 Strict-Transport-Security 頭后,在所設(shè)置的過期時(shí)間內(nèi)當(dāng)前域名就必須使用 HTTPS 協(xié)議進(jìn)行訪問,無法再通過 HTTP 訪問,如果還需要通過 HTTP 訪問只能更換域名(在服務(wù)端重定向至 HTTP 的新域名),使用時(shí)請注意。

注:已在 RFC 6797 中標(biāo)準(zhǔn)化。

X-Accel-Redirect

Nginx 后端響應(yīng)頭

參考:https://www.nginx.com/resources/wiki/start/topics/examples/x-accel

當(dāng)客戶端發(fā)起請求下載某個(gè)文件時(shí),因?yàn)椴]有 X-Accel-Redirect 頭,Web 服務(wù)器并不會立刻就把文件輸出給客戶端;而是將這個(gè)請求交給后端的程序語言,程序語言驗(yàn)證認(rèn)為該客戶端可以下載這個(gè)文件,就寫出相應(yīng)的 X-Accel-Redirect 頭并結(jié)束處理;X-Accel-Redirect 頭返回時(shí)經(jīng)過前端的 Web 服務(wù)器,Web 服務(wù)器檢查到這個(gè)頭之后,才把文件輸出到客戶端。

如果客戶端偽造一個(gè) X-Accel-Redirect 頭來讀取呢?當(dāng)然也是不能下載的,因?yàn)閣eb服務(wù)器只認(rèn)識后端發(fā)來的 X-Accel-Redirect 頭,客戶端發(fā)來的不算。

Nginx 還有很多 X-Accel 相關(guān)的參數(shù),比如速度、緩沖、字符集等,參考 Nginx 的 X-Accel 文檔。

X-Accel-Redirect: /mp3/1.mp3

X-Content-Type-Options

即使給一個(gè) html 文檔指定 Content-Type 為“text/plain”,在 IE8 中這個(gè)文檔依然會被當(dāng)做 HTML 來解析。利用瀏覽器的這個(gè)特性,攻擊者甚至可以讓原本應(yīng)該解析為圖片的請求被解析為 JavaScript。通過下面這個(gè)響應(yīng)頭可以禁用瀏覽器的類型猜測行為。這個(gè)響應(yīng)頭的值只能是 nosniff,可用于 IE8+ 和 Chrome。

X-Content-Type-Options: nosniff

X-Frame-Options

點(diǎn)擊劫持(Clickjacking)保護(hù)。

  • deny 表示在 frame 中頁面不呈現(xiàn)
  • sameorigin 表示在 frame 中如果源地址不一致時(shí)頁面不呈現(xiàn)
  • allow-from 表示允許指定的地址
  • allowall 非標(biāo)準(zhǔn),允許任一地址
X-Frame-Options: deny

注:已在 RFC 7034 中標(biāo)準(zhǔn)化。

X-XSS-Protection

參考:https://blogs.msdn.microsoft.com/ieinternals/2011/01/31/controlling-the-xss-filter/

跨站腳本攻擊 (XSS)過濾器,有以下幾種配置:

  • 0 禁用 XSS 保護(hù)
  • 1 啟用 XSS 保護(hù)
  • 1; mode=block 啟用 XSS 保護(hù),并在檢查到 XSS 攻擊時(shí),停止渲染頁面(例如 IE8 中,檢查到攻擊時(shí),整個(gè)頁面會被一個(gè) # 替換)
X-XSS-Protection: 1; mode=block

參考

  1. 一些安全相關(guān)的 HTTP 響應(yīng)頭, https://imququ.com/post/web-security-and-response-header.html
  2. Content Security Policy 介紹,https://imququ.com/post/content-security-policy-reference.html
  3. HTTP 頭字段列表,https://zh.wikipedia.org/wiki/HTTP%E5%A4%B4%E5%AD%97%E6%AE%B5%E5%88%97%E8%A1%A8
  4. List of HTTP header fields, https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容