前言
在上一篇文章中,我們學習了 TCP/IP 協定的基礎知識。現在,讓我們往上一層,深入了解應用層中最重要的協定之一:HTTP。
HTTP(HyperText Transfer Protocol)是網際網路的基石。每當你瀏覽網頁、使用 API、進行線上購物,背後都是 HTTP 在運作。對資安人員來說,理解 HTTP 的每一個細節至關重要——無論是進行 Web 滲透測試、分析惡意流量、還是設定安全防護,HTTP 知識都是必備的基礎。
這篇文章將深入剖析 HTTP 的三大核心要素:Request Method(請求方法)、Header(標頭)、以及 Status Code(狀態碼)。
HTTP 基礎回顧
HTTP 是什麼?
HTTP 是一種「請求-回應」(Request-Response)協定。客戶端(通常是瀏覽器)發送請求給伺服器,伺服器處理後回傳回應。
┌──────────┐ ┌──────────┐
│ │ ───── HTTP Request ─────► │ │
│ 客戶端 │ │ 伺服器 │
│ (瀏覽器) │ ◄──── HTTP Response ──── │ (網站) │
└──────────┘ └──────────┘
HTTP 訊息結構
無論是請求還是回應,HTTP 訊息都由三個部分組成:
HTTP 請求(Request)結構:
┌─────────────────────────────────────────────────────┐
│ POST /login HTTP/1.1 ← 請求行 │
├─────────────────────────────────────────────────────┤
│ Host: www.example.com ← 標頭區塊 │
│ Content-Type: application/json │
│ User-Agent: Mozilla/5.0 │
│ Cookie: session=abc123 │
├─────────────────────────────────────────────────────┤
│ ← 空行 │
├─────────────────────────────────────────────────────┤
│ {"username":"admin","password":"1234"} ← 請求主體 │
└─────────────────────────────────────────────────────┘
HTTP 回應(Response)結構:
┌─────────────────────────────────────────────────────┐
│ HTTP/1.1 200 OK ← 狀態行 │
├─────────────────────────────────────────────────────┤
│ Content-Type: text/html; charset=utf-8 ← 標頭區塊 │
│ Content-Length: 1234 │
│ Set-Cookie: session=xyz789 │
├─────────────────────────────────────────────────────┤
│ ← 空行 │
├─────────────────────────────────────────────────────┤
│ <!DOCTYPE html> ← 回應主體 │
│ <html>...</html> │
└─────────────────────────────────────────────────────┘
HTTP 版本演進
| 版本 | 年份 | 特點 |
|---|---|---|
| HTTP/0.9 | 1991 | 最初版本,只支援 GET,無標頭 |
| HTTP/1.0 | 1996 | 加入標頭、狀態碼、POST 方法 |
| HTTP/1.1 | 1997 | 持久連線、管線化、Host 標頭 |
| HTTP/2 | 2015 | 二進位協定、多工、標頭壓縮 |
| HTTP/3 | 2022 | 基於 QUIC(UDP)、更低延遲 |
目前最常見的仍是 HTTP/1.1,但 HTTP/2 和 HTTP/3 的使用率正在快速增長。
HTTP Method(請求方法)
HTTP Method 定義了客戶端想對資源執行什麼操作。這是每個 HTTP 請求的第一個關鍵資訊。
常用 Method 一覽
| Method | 用途 | 是否有請求主體 | 是否冪等 | 是否安全 |
|---|---|---|---|---|
| GET | 取得資源 | 否 | 是 | 是 |
| POST | 提交資料/建立資源 | 是 | 否 | 否 |
| PUT | 更新/取代資源 | 是 | 是 | 否 |
| PATCH | 部分更新資源 | 是 | 否 | 否 |
| DELETE | 刪除資源 | 可選 | 是 | 否 |
| HEAD | 取得標頭(不含主體) | 否 | 是 | 是 |
| OPTIONS | 查詢支援的方法 | 否 | 是 | 是 |
| TRACE | 迴路測試 | 否 | 是 | 是 |
| CONNECT | 建立隧道 | 否 | 否 | 否 |
名詞解釋:
– 冪等(Idempotent):執行多次與執行一次的結果相同
– 安全(Safe):不會修改伺服器上的資源
GET
GET 是最常見的方法,用於請求取得資源。
GET /articles/123 HTTP/1.1
Host: www.example.com
Accept: text/html
特點:
– 參數放在 URL 的查詢字串中(Query String)
– 會被瀏覽器快取
– 會留在瀏覽器歷史紀錄中
– 可以被加入書籤
– URL 長度有限制(約 2048 字元,依瀏覽器而異)
範例 URL:
https://example.com/search?q=security&page=1&sort=date
└──────── Query String ────────┘
資安注意事項
❌ 不安全的做法:
GET /login?username=admin&password=secret123 HTTP/1.1
問題:
1. 密碼出現在 URL 中
2. 會被記錄在瀏覽器歷史
3. 會被記錄在伺服器日誌
4. 可能被 Referer 標頭洩露給第三方
永遠不要用 GET 傳送敏感資料!
POST
POST 用於提交資料給伺服器,通常用於表單提交、建立新資源。
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 56
{"username": "newuser", "email": "[email protected]"}
特點:
– 資料放在請求主體中
– 不會被快取(預設)
– 不會留在瀏覽器歷史
– 沒有資料大小限制(伺服器可能會限制)
– 不是冪等的:多次提交可能建立多筆資料
常見的 Content-Type:
# 表單資料(預設)
Content-Type: application/x-www-form-urlencoded
username=admin&password=secret
# JSON 資料
Content-Type: application/json
{"username": "admin", "password": "secret"}
# 檔案上傳
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
PUT
PUT 用於更新或取代整個資源。
PUT /api/users/123 HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"id": 123,
"username": "updateduser",
"email": "[email protected]",
"role": "admin"
}
PUT vs POST:
– PUT 是冪等的:多次執行結果相同
– PUT 通常用於更新已存在的資源
– PUT 需要提供完整的資源內容
PATCH
PATCH 用於部分更新資源,只需提供要修改的欄位。
PATCH /api/users/123 HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"email": "[email protected]"
}
PATCH vs PUT:
– PATCH 只需提供要更新的欄位
– PUT 需要提供完整的資源
DELETE
DELETE 用於刪除資源。
DELETE /api/users/123 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
資安注意事項
DELETE 操作應該要有適當的權限控制:
– 驗證使用者身份
– 確認使用者有權限刪除該資源
– 考慮使用軟刪除(soft delete)而非真正刪除
HEAD
HEAD 與 GET 類似,但回應只包含標頭,不包含主體。常用於:
– 檢查資源是否存在
– 取得資源的 metadata(如檔案大小、最後修改時間)
– 測試連結是否有效
HEAD /large-file.zip HTTP/1.1
Host: download.example.com
回應:
HTTP/1.1 200 OK
Content-Type: application/zip
Content-Length: 1073741824
Last-Modified: Mon, 15 Jan 2025 10:30:00 GMT
OPTIONS
OPTIONS 用於查詢伺服器支援哪些方法,也用於 CORS 預檢請求。
OPTIONS /api/users HTTP/1.1
Host: api.example.com
Origin: https://frontend.example.com
Access-Control-Request-Method: POST
回應:
HTTP/1.1 204 No Content
Allow: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
TRACE
TRACE 會將收到的請求原封不動地回傳,用於診斷。
TRACE / HTTP/1.1
Host: www.example.com
資安注意事項:Cross-Site Tracing (XST)
TRACE 方法可能被用於竊取 HttpOnly Cookie:
- 攻擊者注入 JavaScript
- JavaScript 發送 TRACE 請求
- 回應中包含完整的請求標頭(含 Cookie)
- 即使 Cookie 設定了 HttpOnly,也會被讀取
建議:在伺服器上停用 TRACE 方法
CONNECT
CONNECT 用於建立到目標伺服器的隧道,通常用於 HTTPS 代理。
CONNECT www.example.com:443 HTTP/1.1
Host: www.example.com
非標準方法
有些應用會使用非標準的 HTTP 方法:
- COPY:複製資源(WebDAV)
- MOVE:移動資源(WebDAV)
- LOCK/UNLOCK:鎖定/解鎖資源(WebDAV)
- PROPFIND:取得屬性(WebDAV)
HTTP Header(標頭)
HTTP Header 包含了請求或回應的額外資訊,是 HTTP 協定中最豐富的部分。
標頭的基本格式
Header-Name: header-value
- 標頭名稱不區分大小寫(但慣例上使用首字母大寫)
- 值前後的空白會被忽略
- 可以有多個同名的標頭
請求標頭(Request Headers)
Host
指定請求的目標主機和埠口,是 HTTP/1.1 唯一必要的標頭。
Host: www.example.com
Host: api.example.com:8080
一台伺服器可能託管多個網站(虛擬主機),Host 標頭讓伺服器知道要處理哪個網站的請求。
User-Agent
識別發送請求的客戶端軟體。
# Chrome 瀏覽器
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
# curl
User-Agent: curl/7.68.0
# Python requests
User-Agent: python-requests/2.28.1
資安應用
- 指紋識別:透過 User-Agent 識別客戶端類型
- 偽造:攻擊者可以偽造 User-Agent 來偽裝身份
- 過濾:WAF 可能根據 User-Agent 阻擋惡意請求
Accept
告訴伺服器客戶端能接受的內容類型。
# 接受 HTML
Accept: text/html
# 接受 JSON
Accept: application/json
# 接受多種類型,有優先順序
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
q 值表示優先順序(0 到 1),預設為 1。
Accept-Language
指定偏好的語言。
Accept-Language: zh-TW, zh;q=0.9, en-US;q=0.8, en;q=0.7
Accept-Encoding
指定支援的壓縮方式。
Accept-Encoding: gzip, deflate, br
Content-Type
指定請求主體的媒體類型。
# 表單資料
Content-Type: application/x-www-form-urlencoded
# JSON
Content-Type: application/json
# 檔案上傳
Content-Type: multipart/form-data; boundary=----FormBoundary
# 純文字
Content-Type: text/plain; charset=utf-8
Content-Length
指定請求主體的位元組長度。
Content-Length: 348
Authorization
用於身份驗證。
# Basic 認證(Base64 編碼的 username:password)
Authorization: Basic YWRtaW46cGFzc3dvcmQ=
# Bearer Token(常用於 OAuth 2.0、JWT)
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# API Key
Authorization: ApiKey your-api-key-here
資安注意事項
- Basic 認證的憑證只是 Base64 編碼,不是加密,必須使用 HTTPS
- Token 應該妥善保管,不要洩露到前端程式碼或日誌中
Cookie
發送儲存在客戶端的 Cookie。
Cookie: session_id=abc123; user_pref=dark_mode; tracking_id=xyz789
Referer
告訴伺服器請求是從哪個頁面發起的。
Referer: https://www.google.com/search?q=example
注意:這個標頭名稱有拼寫錯誤(應該是 Referrer),但因為歷史原因保留了下來。
資安應用
- CSRF 防護:檢查 Referer 是否來自合法來源
- 資訊洩露:Referer 可能洩露敏感資訊(如搜尋關鍵字、內部 URL)
Origin
與 Referer 類似,但只包含協定、主機和埠口,用於 CORS。
Origin: https://www.example.com
X-Forwarded-For
記錄經過的代理伺服器和原始客戶端 IP。
X-Forwarded-For: 203.0.113.50, 70.41.3.18, 150.172.238.178
原始客戶端 IP 代理1 代理2
資安注意事項
- 這個標頭可以被偽造
- 不應該完全信任此標頭來做安全決策
- 應該只信任可信代理添加的值
X-Requested-With
通常用於識別 AJAX 請求。
X-Requested-With: XMLHttpRequest
回應標頭(Response Headers)
Content-Type
指定回應主體的媒體類型。
Content-Type: text/html; charset=utf-8
Content-Type: application/json
Content-Type: image/png
Content-Length
回應主體的位元組長度。
Content-Length: 12345
Content-Encoding
回應使用的壓縮方式。
Content-Encoding: gzip
Set-Cookie
設定 Cookie 到客戶端。
Set-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=3600
Cookie 屬性詳解:
| 屬性 | 說明 | 資安意義 |
|---|---|---|
| Path | Cookie 適用的路徑 | 限制 Cookie 的作用範圍 |
| Domain | Cookie 適用的網域 | 控制跨子網域存取 |
| Expires/Max-Age | 過期時間 | 控制 Cookie 生命週期 |
| HttpOnly | 禁止 JavaScript 存取 | 防止 XSS 竊取 Cookie |
| Secure | 只透過 HTTPS 傳送 | 防止中間人攻擊 |
| SameSite | 跨站請求限制 | 防止 CSRF 攻擊 |
SameSite 值:
– Strict:完全禁止跨站請求攜帶 Cookie
– Lax:允許部分跨站請求(如導航連結)
– None:允許跨站請求(需搭配 Secure)
Location
用於重導向,指定新的 URL。
HTTP/1.1 302 Found
Location: https://www.example.com/new-page
Cache-Control
控制快取行為。
# 禁止快取
Cache-Control: no-store
# 可以快取,但每次都要驗證
Cache-Control: no-cache
# 可以快取 1 小時
Cache-Control: max-age=3600
# 私有快取(只有瀏覽器可以快取,CDN 不行)
Cache-Control: private, max-age=3600
# 公開快取
Cache-Control: public, max-age=86400
ETag
資源的版本標識,用於快取驗證。
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Last-Modified
資源的最後修改時間。
Last-Modified: Wed, 15 Jan 2025 10:30:00 GMT
Server
伺服器軟體資訊。
Server: nginx/1.18.0
Server: Apache/2.4.41 (Ubuntu)
資安注意事項
暴露伺服器版本可能讓攻擊者更容易找到已知漏洞。建議在生產環境隱藏或模糊化此標頭。
安全相關標頭
這些標頭對 Web 安全至關重要,資安人員必須熟悉。
Strict-Transport-Security (HSTS)
強制瀏覽器只能用 HTTPS 連接。
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age:記住這個設定的秒數includeSubDomains:子網域也適用preload:申請加入瀏覽器內建的 HSTS 清單
防護效果:防止 SSL Stripping 攻擊
X-Content-Type-Options
防止瀏覽器 MIME 類型嗅探。
X-Content-Type-Options: nosniff
防護效果:防止將非腳本檔案當作腳本執行
X-Frame-Options
控制頁面是否可以被嵌入 iframe。
# 完全禁止
X-Frame-Options: DENY
# 只允許同源
X-Frame-Options: SAMEORIGIN
# 允許指定來源(已廢棄,建議用 CSP)
X-Frame-Options: ALLOW-FROM https://trusted.com
防護效果:防止 Clickjacking 攻擊
Content-Security-Policy (CSP)
強大的安全標頭,控制頁面可以載入哪些資源。
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' 'unsafe-inline'; img-src *; frame-ancestors 'none'
常用指令:
| 指令 | 說明 |
|---|---|
| default-src | 預設來源 |
| script-src | JavaScript 來源 |
| style-src | CSS 來源 |
| img-src | 圖片來源 |
| font-src | 字型來源 |
| connect-src | AJAX/WebSocket 來源 |
| frame-src | iframe 來源 |
| frame-ancestors | 誰可以嵌入此頁面 |
| form-action | 表單可以提交到哪裡 |
來源值:
| 值 | 說明 |
|---|---|
| ‘self’ | 同源 |
| ‘none’ | 禁止所有 |
| ‘unsafe-inline’ | 允許 inline(不建議) |
| ‘unsafe-eval’ | 允許 eval()(不建議) |
| https: | 只允許 HTTPS |
| data: | 允許 data: URI |
| 特定網域 | 如 https://cdn.example.com |
防護效果:顯著降低 XSS 攻擊的影響
X-XSS-Protection
啟用瀏覽器內建的 XSS 過濾器(舊版瀏覽器)。
X-XSS-Protection: 1; mode=block
注意:現代瀏覽器已移除此功能,建議使用 CSP 代替。
Referrer-Policy
控制 Referer 標頭的發送策略。
# 完全不發送
Referrer-Policy: no-referrer
# 同源才發送
Referrer-Policy: same-origin
# 降級時不發送(HTTPS → HTTP)
Referrer-Policy: no-referrer-when-downgrade
# 只發送來源(不含路徑)
Referrer-Policy: origin
# 同源發送完整,跨域發送來源
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy
控制瀏覽器功能的使用權限(原 Feature-Policy)。
Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(self)
可控制的功能包括:geolocation、camera、microphone、payment、usb、fullscreen 等。
安全標頭檢查清單
# 完整的安全標頭配置範例
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=(), microphone=()
CORS 相關標頭
CORS(Cross-Origin Resource Sharing)控制跨域資源存取。
請求標頭
Origin: https://frontend.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization
回應標頭
# 允許的來源
Access-Control-Allow-Origin: https://frontend.example.com
# 或允許所有(不建議)
Access-Control-Allow-Origin: *
# 允許的方法
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
# 允許的標頭
Access-Control-Allow-Headers: Content-Type, Authorization
# 是否允許攜帶憑證(Cookie)
Access-Control-Allow-Credentials: true
# 預檢請求的快取時間
Access-Control-Max-Age: 86400
資安注意事項
# ❌ 危險配置:允許所有來源 + 允許憑證
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
# 這個配置瀏覽器會拒絕執行
# ❌ 危險配置:動態反射 Origin 標頭
Access-Control-Allow-Origin: [直接複製請求的 Origin]
Access-Control-Allow-Credentials: true
# 允許任何網站存取帶憑證的請求
# ✓ 正確做法:白名單驗證
# 伺服器端檢查 Origin 是否在允許清單中
HTTP Status Code(狀態碼)
狀態碼是三位數的數字,告訴客戶端請求的處理結果。
狀態碼分類
| 範圍 | 類別 | 說明 |
|---|---|---|
| 1xx | Informational | 資訊回應,請求已接收,繼續處理 |
| 2xx | Successful | 成功,請求已被接受並處理 |
| 3xx | Redirection | 重導向,需要進一步操作 |
| 4xx | Client Error | 客戶端錯誤 |
| 5xx | Server Error | 伺服器錯誤 |
1xx 資訊回應
100 Continue
伺服器已收到請求標頭,客戶端可以繼續發送請求主體。
101 Switching Protocols
伺服器同意切換協定(如升級到 WebSocket)。
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
103 Early Hints
在最終回應之前提示客戶端預載資源(HTTP/2+)。
2xx 成功
200 OK
請求成功,回應中包含請求的資源。
201 Created
請求成功,新資源已建立。通常用於 POST 請求。
HTTP/1.1 201 Created
Location: /api/users/456
Content-Type: application/json
{"id": 456, "username": "newuser"}
202 Accepted
請求已接受,但尚未處理完成。常用於非同步操作。
204 No Content
請求成功,但沒有回應內容。常用於 DELETE 或 PUT 成功後。
HTTP/1.1 204 No Content
206 Partial Content
回應部分內容,用於範圍請求(如續傳下載)。
HTTP/1.1 206 Partial Content
Content-Range: bytes 1000-1999/5000
3xx 重導向
301 Moved Permanently
資源已永久移動到新位置。搜尋引擎會更新索引。
HTTP/1.1 301 Moved Permanently
Location: https://www.example.com/new-url
302 Found
資源暫時移動到新位置。
HTTP/1.1 302 Found
Location: https://www.example.com/temporary-url
303 See Other
用於 POST 請求後的重導向,客戶端應使用 GET 請求新位置。
304 Not Modified
資源未修改,客戶端可以使用快取版本。
HTTP/1.1 304 Not Modified
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
307 Temporary Redirect
類似 302,但保持原始的請求方法。
308 Permanent Redirect
類似 301,但保持原始的請求方法。
4xx 客戶端錯誤
400 Bad Request
請求格式錯誤,伺服器無法理解。
HTTP/1.1 400 Bad Request
Content-Type: application/json
{"error": "Invalid JSON format"}
401 Unauthorized
需要身份驗證。
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"
403 Forbidden
伺服器理解請求,但拒絕執行。已驗證身份但沒有權限。
401 vs 403
- 401:「你是誰?請先登入」
- 403:「我知道你是誰,但你沒有權限」
404 Not Found
找不到請求的資源。
資安應用
- 有時會故意對存在但無權存取的資源回傳 404,避免洩露資源存在與否
- 攻擊者可能透過不同的回應來列舉有效的使用者名稱或資源
405 Method Not Allowed
不支援請求的方法。
HTTP/1.1 405 Method Not Allowed
Allow: GET, POST
406 Not Acceptable
伺服器無法產生客戶端可接受的回應格式。
408 Request Timeout
客戶端發送請求太慢,伺服器超時。
409 Conflict
請求與目前資源狀態衝突。
HTTP/1.1 409 Conflict
Content-Type: application/json
{"error": "Username already exists"}
410 Gone
資源已永久刪除,不再可用。與 404 不同的是,410 表示資源曾經存在。
411 Length Required
伺服器要求 Content-Length 標頭。
413 Payload Too Large
請求內容太大。
HTTP/1.1 413 Payload Too Large
Retry-After: 3600
414 URI Too Long
URL 太長。
415 Unsupported Media Type
不支援的內容類型。
HTTP/1.1 415 Unsupported Media Type
Content-Type: application/json
{"error": "Content-Type must be application/json"}
418 I’m a teapot
茶壺無法煮咖啡(來自愚人節 RFC 2324)。
422 Unprocessable Entity
請求格式正確,但語義錯誤。
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{"errors": {"email": "Invalid email format"}}
429 Too Many Requests
請求太頻繁,速率限制。
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705320000
資安應用
速率限制是防禦暴力破解、DDoS 的重要機制。
5xx 伺服器錯誤
500 Internal Server Error
伺服器遇到未預期的錯誤。
資安注意事項
- 生產環境不應該回傳詳細的錯誤訊息和堆疊追蹤
- 這些資訊可能幫助攻擊者了解系統內部結構
501 Not Implemented
伺服器不支援請求的功能。
502 Bad Gateway
作為閘道器或代理的伺服器收到無效的回應。
503 Service Unavailable
伺服器暫時無法處理請求(維護或過載)。
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
504 Gateway Timeout
閘道器或代理伺服器等待後端回應超時。
狀態碼速查表
常見狀態碼:
2xx 成功
├── 200 OK - 成功
├── 201 Created - 已建立
├── 204 No Content - 成功但無內容
3xx 重導向
├── 301 Moved Permanently - 永久移動
├── 302 Found - 暫時移動
├── 304 Not Modified - 使用快取
4xx 客戶端錯誤
├── 400 Bad Request - 請求格式錯誤
├── 401 Unauthorized - 需要驗證
├── 403 Forbidden - 沒有權限
├── 404 Not Found - 找不到
├── 405 Method Not Allowed- 方法不允許
├── 429 Too Many Requests - 請求太頻繁
5xx 伺服器錯誤
├── 500 Internal Error - 伺服器錯誤
├── 502 Bad Gateway - 閘道錯誤
├── 503 Service Unavailable- 服務不可用
├── 504 Gateway Timeout - 閘道超時
實戰工具與操作
使用瀏覽器開發者工具
按 F12 開啟開發者工具,切換到「Network」分頁:
- 重新載入頁面
- 點擊任一請求
- 查看 Headers 分頁:可以看到請求和回應的所有標頭
- 查看 Response 分頁:可以看到回應內容
使用 curl
curl 是命令列的 HTTP 工具,資安人員必備。
# 基本 GET 請求
curl https://www.example.com
# 顯示回應標頭
curl -I https://www.example.com
# 顯示詳細資訊(包含請求標頭)
curl -v https://www.example.com
# POST 請求
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"username": "test", "password": "secret"}'
# 帶 Cookie 的請求
curl -b "session=abc123" https://www.example.com/dashboard
# 設定 Cookie
curl -c cookies.txt https://www.example.com/login
# 跟隨重導向
curl -L https://example.com
# 忽略 SSL 憑證錯誤(測試用)
curl -k https://self-signed.example.com
# 設定自訂標頭
curl -H "Authorization: Bearer token123" \
-H "X-Custom-Header: value" \
https://api.example.com
# 上傳檔案
curl -X POST https://api.example.com/upload \
-F "file=@/path/to/file.pdf"
# 只顯示回應碼
curl -s -o /dev/null -w "%{http_code}" https://example.com
使用 HTTPie
HTTPie 是更友善的命令列 HTTP 工具。
# 安裝
pip install httpie
# GET 請求
http https://api.example.com/users
# POST 請求
http POST https://api.example.com/users username=test password=secret
# 帶標頭
http https://api.example.com/users Authorization:"Bearer token123"
# 上傳 JSON 檔案
http POST https://api.example.com/data < data.json
使用 Burp Suite
Burp Suite 是 Web 安全測試的瑞士刀:
- Proxy:攔截和修改 HTTP 請求/回應
- Repeater:重送和修改請求
- Intruder:自動化測試(暴力破解、模糊測試)
- Scanner:自動掃描漏洞(Pro 版)
基本使用流程:
1. 設定瀏覽器代理指向 Burp(預設 127.0.0.1:8080)
2. 在 Proxy 分頁開啟攔截
3. 瀏覽網站,Burp 會攔截所有請求
4. 可以修改請求後轉發,或發送到其他工具
檢查安全標頭
使用線上工具檢查網站的安全標頭:
- securityheaders.com:掃描並評分安全標頭配置
- observatory.mozilla.org:Mozilla 的安全檢查工具
使用 curl 手動檢查:
# 檢查所有回應標頭
curl -I https://www.example.com
# 檢查特定標頭
curl -sI https://www.example.com | grep -i "strict-transport-security"
curl -sI https://www.example.com | grep -i "content-security-policy"
curl -sI https://www.example.com | grep -i "x-frame-options"
常見攻擊與 HTTP 的關係
HTTP Request Smuggling
當前端代理和後端伺服器對請求邊界的理解不一致時,可能導致請求走私。
POST / HTTP/1.1
Host: vulnerable.com
Content-Length: 13
Transfer-Encoding: chunked
0
SMUGGLED
Host Header Injection
篡改 Host 標頭可能導致:
– 密碼重設連結指向惡意網站
– Web Cache Poisoning
– 繞過存取控制
GET /reset-password HTTP/1.1
Host: evil.com
X-Forwarded-Host: evil.com
HTTP Response Splitting
如果使用者輸入未經處理就放入回應標頭,可能導致回應分割:
# 惡意輸入
name=John%0d%0aSet-Cookie:%20session=evil
# 導致的回應
HTTP/1.1 200 OK
Content-Type: text/html
X-Name: John
Set-Cookie: session=evil
Cache Poisoning
透過操縱請求使快取儲存惡意內容:
- 發送帶有惡意 payload 的請求
- 回應被快取
- 其他使用者存取相同資源時收到惡意內容
延伸閱讀
RFC 文件
- RFC 9110:HTTP Semantics
- RFC 9111:HTTP Caching
- RFC 9112:HTTP/1.1
- RFC 9113:HTTP/2
- RFC 9114:HTTP/3
線上資源
- MDN Web Docs:https://developer.mozilla.org/en-US/docs/Web/HTTP
- OWASP:https://owasp.org/www-project-web-security-testing-guide/
- PortSwigger Web Security Academy:https://portswigger.net/web-security
推薦工具
- Burp Suite:Web 安全測試必備
- OWASP ZAP:開源的 Web 安全掃描器
- Postman:API 測試工具
- Fiddler:Windows 上的 HTTP 調試代理
總結
這篇文章深入探討了 HTTP 協定的三大核心要素:
HTTP Method
– 理解 GET、POST、PUT、DELETE 等方法的用途和差異
– 知道何時該用哪種方法
– 了解方法相關的安全考量
HTTP Header
– 熟悉常見的請求和回應標頭
– 掌握安全相關標頭的配置
– 了解 CORS 的運作機制
HTTP Status Code
– 理解各類狀態碼的含義
– 能夠根據狀態碼判斷問題所在
– 知道狀態碼在安全測試中的應用
對資安人員來說,HTTP 是每天都會接觸到的協定。無論是:
– 使用 Burp Suite 進行滲透測試
– 分析網路流量找出攻擊跡象
– 評估 Web 應用的安全配置
– 開發安全的 Web 服務
都需要對 HTTP 有深入的理解。
下一步,你可以:
– 用 Burp Suite 攔截並分析真實的 HTTP 流量
– 檢查你常用網站的安全標頭配置
– 學習 OWASP Top 10 中與 HTTP 相關的漏洞
– 嘗試在 PortSwigger Web Security Academy 練習相關題目

