3、HTTP协议基础:请求与响应结构、常见方法、状态码、Cookie与Session机制

做Web安全测试,HTTP协议是绕不开的基础。说白了,你连浏览器和服务器之间怎么“对话”都不清楚,那漏洞挖掘基本就是瞎蒙。我个人习惯,拿到一个目标站点,第一件事就是打开开发者工具,看网络请求。这比什么扫描器都靠谱。

3.1 请求与响应结构:一次完整的对话

HTTP的通信模型很简单:客户端发请求,服务器回响应。就像你点菜,服务员下单,厨房出菜。咱们先看看请求长什么样。

3.1.1 请求报文结构

一个典型的HTTP请求,由三部分组成:

  • 请求行:包含方法、URL、协议版本
  • 请求头:一堆键值对,携带元数据
  • 请求体:可选,POST请求时携带数据

举个例子,你访问一个登录页面,浏览器实际发送的是这样的东西:

POST /login HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
Cookie: session_id=abc123

username=admin&password=123456

嗯,这里要注意。请求行里的POST是方法,/login是路径,HTTP/1.1是版本。请求头里每一行都是一个字段,最后空一行,然后是请求体。这个结构,做安全测试时必须烂熟于心。

重点:请求头中的Host字段经常被忽略,但它是HTTP/1.1中唯一必须的字段。我在项目中遇到过,有些开发者用Host字段做虚拟主机路由,结果被Host头注入攻击搞崩了。

3.1.2 响应报文结构

服务器收到请求后,会返回一个响应。结构类似:

  • 状态行:协议版本、状态码、状态描述
  • 响应头:服务器信息、内容类型、缓存策略等
  • 响应体:实际返回的数据,比如HTML、JSON

看个例子:

HTTP/1.1 200 OK
Date: Mon, 15 Jan 2024 12:00:00 GMT
Server: Apache/2.4.41
Content-Type: text/html; charset=utf-8
Set-Cookie: session_id=xyz789; Path=/
Content-Length: 1234

<html>
<body>登录成功!</body>
</html>

你想想看,响应头里的Set-Cookie字段,就是服务器让浏览器种Cookie的地方。这个机制,后面会详细讲。

3.2 常见HTTP方法:不只是GET和POST

很多人以为HTTP方法就GET和POST两种。其实远不止。做安全测试,你得知道每个方法背后的含义。

方法 含义 安全测试关注点
GET 获取资源 参数在URL中,容易泄露敏感信息
POST 提交数据 请求体可被篡改,注意CSRF
PUT 上传/替换资源 可能被用来上传恶意文件
DELETE 删除资源 权限校验不严可导致任意删除
OPTIONS 查询支持的方法 可探测服务器允许哪些方法
PATCH 部分更新资源 参数校验不当可导致数据篡改

我的经验:我曾经测试过一个RESTful API,开发者只限制了GET和POST,但忘了禁用PUT和DELETE。结果我用PUT方法直接覆盖了其他用户的配置文件。嗯,这个漏洞在CVSS评分里能拿8分以上。

为什么会这样?很多框架默认开启所有方法,开发者只关注业务逻辑,忽略了方法级别的访问控制。所以,我建议你在做渗透测试时,先用OPTIONS方法探一下服务器支持哪些方法。

3.3 状态码:服务器在说什么?

状态码是服务器对请求的“态度”。做安全测试,状态码能告诉你很多信息。比如,一个登录接口返回200,说明成功了;返回403,说明被拒绝了;返回500,说明服务器内部出错了。

常见的状态码分类:

  • 1xx(信息性):很少见,比如101表示协议切换
  • 2xx(成功):200 OK,201 Created,204 No Content
  • 3xx(重定向):301永久重定向,302临时重定向,304未修改
  • 4xx(客户端错误):400 Bad Request,401未授权,403禁止访问,404未找到,405方法不允许
  • 5xx(服务器错误):500内部错误,502 Bad Gateway,503服务不可用

避坑指南:我曾经遇到一个站点,所有未授权访问都返回302重定向到登录页。但有一个接口返回了404。你猜怎么着?这个接口其实存在,只是开发者忘了加权限校验。所以,状态码的差异本身就是信息泄露。

做安全测试时,我特别关注403和404的区别。403表示“我知道这个资源存在,但你不许访问”;404表示“我不知道你在说什么”。如果某个路径返回403,说明它存在,只是被权限控制挡住了。这时候,可以尝试绕过。

3.4 Cookie与Session机制:谁在记住你?

HTTP是无状态的。什么意思?就是服务器默认不记得你是谁。你第一次请求和第二次请求,对服务器来说完全是两个人。那网站怎么记住你的登录状态?靠Cookie和Session。

3.4.1 Cookie:客户端的“小纸条”

Cookie是服务器让浏览器保存的一小段数据。每次请求,浏览器都会自动带上它。结构很简单:

Set-Cookie: session_id=abc123; Path=/; Domain=.example.com; HttpOnly; Secure; SameSite=Lax

这里有几个关键属性:

  • Name=Value:键值对,比如session_id=abc123
  • Path:指定哪些路径需要携带这个Cookie
  • Domain:指定哪些域名需要携带
  • HttpOnly:禁止JavaScript访问,防止XSS窃取
  • Secure:只在HTTPS下传输
  • SameSite:控制跨站请求时是否携带,防止CSRF

安全要点:我见过太多网站没设置HttpOnly和Secure属性。这意味着,只要有一个XSS漏洞,攻击者就能通过document.cookie直接偷走你的Session。所以,做安全测试时,先检查Cookie的属性。

3.4.2 Session:服务端的“档案袋”

Session是服务器端保存的用户状态数据。通常,服务器会生成一个唯一的Session ID,通过Cookie发给浏览器。浏览器下次请求时带上这个ID,服务器就能找到对应的Session数据。

流程是这样的:

  1. 用户登录成功,服务器创建Session,生成Session ID
  2. 服务器通过Set-Cookie把Session ID发给浏览器
  3. 浏览器后续请求自动带上这个Cookie
  4. 服务器根据Session ID查找对应的Session数据

你想想看,如果Session ID被猜出来或者被偷了,攻击者就能冒充你。这就是Session劫持。

我的建议:做安全测试时,重点关注Session ID的生成算法。如果它是可预测的(比如自增数字、时间戳),那就可以尝试暴力破解。我曾经测试过一个系统,Session ID就是MD5(用户名+时间戳),结果我写了个脚本,几分钟就猜出了管理员的Session。

3.4.3 Cookie vs Session:区别在哪?

特性 Cookie Session
存储位置 客户端(浏览器) 服务器端
数据容量 4KB左右 理论上无限制
安全性 容易被篡改和窃取 相对安全,但Session ID需保护
生命周期 可设置过期时间 通常随浏览器关闭或超时失效
性能影响 每次请求携带,增加带宽 占用服务器内存

说白了,Cookie是存在你手机里的便签,Session是存在服务器里的档案。便签丢了,档案还在,但需要便签上的编号才能找到档案。

3.5 安全测试中的HTTP协议实战

理论讲完了,咱们看看实际怎么用。做Web安全测试时,我通常会做这几件事:

  1. 抓包分析:用Burp Suite或浏览器开发者工具,看每个请求的完整结构
  2. 方法探测:用OPTIONS方法看服务器支持哪些HTTP方法
  3. 状态码分析:关注403和404的区别,寻找隐藏接口
  4. Cookie检查:看有没有HttpOnly、Secure、SameSite属性
  5. Session测试:尝试修改Session ID,看能否越权访问

避坑指南:我曾经测试一个金融系统,发现它的Session ID在URL中传递(而不是Cookie)。这意味着,只要用户把链接分享给别人,Session就泄露了。这种设计在安全测试中属于高危漏洞。

嗯,HTTP协议看起来简单,但里面门道很多。做安全测试,你得学会“读”请求和响应。每一行头字段,每一个状态码,都可能藏着漏洞的线索。我个人习惯,每测一个站点,先花10分钟看它的HTTP交互模式。这比直接上扫描器有效得多。

记住一句话:不懂HTTP协议的安全测试,就是瞎猫碰死耗子。把基础打牢,后面讲SQL注入、XSS、CSRF的时候,你才能理解攻击为什么能成功,防御为什么有效。