目录
[1.3SYN Flood 攻击利用的是哪一步的漏洞?](#1.3SYN Flood 攻击利用的是哪一步的漏洞?)
[2.2TIME_WAIT 状态为什么必须等待 2MSL?](#2.2TIME_WAIT 状态为什么必须等待 2MSL?)
[2.3TIME_WAIT 过多会有什么问题?如何优化?](#2.3TIME_WAIT 过多会有什么问题?如何优化?)
[3.1HTTP/1.1、HTTP/2、HTTP/3 核心区别](#3.1HTTP/1.1、HTTP/2、HTTP/3 核心区别)
[3.2HTTP/2 的多路复用如何解决 HTTP/1.1 的队头阻塞?](#3.2HTTP/2 的多路复用如何解决 HTTP/1.1 的队头阻塞?)
[HTTP/1.1 的队头阻塞(Head-of-Line Blocking)](#HTTP/1.1 的队头阻塞(Head-of-Line Blocking))
[HTTP/2 的多路复用(Multiplexing)](#HTTP/2 的多路复用(Multiplexing))
[但 HTTP/2 仍有 TCP 层队头阻塞](#但 HTTP/2 仍有 TCP 层队头阻塞)
[HTTP/3 为什么用 QUIC 而不是 TCP?](#HTTP/3 为什么用 QUIC 而不是 TCP?)
[原因 1:彻底解决队头阻塞](#原因 1:彻底解决队头阻塞)
[原因 2:更快的连接建立(0-RTT)](#原因 2:更快的连接建立(0-RTT))
[原因 3:连接迁移(Connection Migration)](#原因 3:连接迁移(Connection Migration))
[原因 4:更好的拥塞控制和流量控制](#原因 4:更好的拥塞控制和流量控制)
[原因 5:避免 TCP 协议僵化(Protocol Ossification)](#原因 5:避免 TCP 协议僵化(Protocol Ossification))
[4.HTTPS 的 TLS 1.2 握手过程是怎样的?](#4.HTTPS 的 TLS 1.2 握手过程是怎样的?)
[TLS 1.3 相比 1.2 有哪些改进?](#TLS 1.3 相比 1.2 有哪些改进?)
[5.GET 和 POST 的区别是什么?](#5.GET 和 POST 的区别是什么?)
[1. 传输安全性](#1. 传输安全性)
[6.SQL 注入、XSS、CSRF 分别针对什么目标?](#6.SQL 注入、XSS、CSRF 分别针对什么目标?)
[一、SQL 注入(SQL Injection)](#一、SQL 注入(SQL Injection))
[二、XSS(跨站脚本攻击,Cross-Site Scripting)](#二、XSS(跨站脚本攻击,Cross-Site Scripting))
[针对目标:浏览器 → 最终用户](#针对目标:浏览器 → 最终用户)
[三、CSRF(跨站请求伪造,Cross-Site Request Forgery)](#三、CSRF(跨站请求伪造,Cross-Site Request Forgery))
[针对目标:用户已认证的会话(Web 应用的操作接口)](#针对目标:用户已认证的会话(Web 应用的操作接口))
1.三次握手
1.1握手细节
- 第一次握手(SYN) :客户端向服务端发送一个 SYN(Synchronize Sequence Numbers)报文段,其中包含客户端生成的初始序列号(Initial Sequence Number,ISN),例如
seq=x。发送后,客户端进入SYN_SENT状态,等待服务端确认。 - 第二次握手(SYN+ACK) :服务端收到 SYN 后,如果同意建立连接,会回复一个 SYN+ACK 报文段。这个报文段包含两个关键信息:
- SYN :服务端也需要同步自己的初始序列号,因此会携带服务端生成的 ISN,例如
seq=y。 - ACK :用于确认收到客户端的 SYN,确认号设置为客户端初始序列号加一,即
ack=x+1。 - 发送该报文段后,服务端进入
SYN_RCVD状态。
- SYN :服务端也需要同步自己的初始序列号,因此会携带服务端生成的 ISN,例如
- 第三次握手(ACK) :客户端收到服务端的 SYN+ACK 后,会向服务端发送最终确认报文段,确认号为
ack=y+1。发送后,客户端进入ESTABLISHED状态。服务端收到这个 ACK 后,也进入ESTABLISHED状态。
1.2为什么需要三次握手
TCP 依赖序列号(SEQ)和确认号(ACK)来保证数据有序、去重和重传。三次握手通过交换并确认双方的 ISN,让两端对"从哪个序号开始收发数据"达成一致,同时避免只凭单向信息就进入已建立状态。
| 步骤 | 报文 | 能确认什么 |
|---|---|---|
| 1 | C→S:SYN | 服务端知道:客户端能发,服务端能收,C→S 方向可达 |
| 2 | S→C:SYN+ACK | 客户端知道:服务端能发,客户端能收;同时确认服务端收到了自己的 SYN |
| 3 | C→S:ACK | 服务端知道:客户端收到了 SYN+ACK,S→C 方向也被服务端确认;至此握手闭环 |
1.3SYN Flood 攻击利用的是哪一步的漏洞?
攻击者大量发送 SYN 包但不进行第三次握手,即返回第二次的ACK,服务端半连接队列(backlog)被填满,正常连接无法建立
2.TCP四次挥手
2.1挥手过程
TCP 是全双工通信,两端的发送方向彼此独立。关闭连接时,通常需要两个方向分别完成"我不发了"和"我确认你不发了"的过程,所以逻辑上常被讲成"四次挥手"。
不过要注意:四次挥手说的是逻辑动作,不一定意味着抓包时总能看到 4 个独立报文段。在某些场景下,ACK 和 FIN 可以合并在同一个报文段里。
典型流程如下:
- 第一次挥手(FIN) :客户端,或者任意一方,决定关闭自己的发送方向时,会发送一个 FIN 报文段,表示自己已经没有数据要发送了。该报文段包含一个序列号,例如
seq=u。发送后,主动关闭方进入FIN_WAIT_1状态。 - 第二次挥手(ACK) :服务端收到 FIN 后,会回复 ACK,确认号为
ack=u+1。发送后,服务端进入CLOSE_WAIT状态。客户端收到 ACK 后,进入FIN_WAIT_2状态。此时连接处于**半关闭(Half-Close)**状态:客户端到服务端的发送方向已关闭,但服务端仍然可以继续向客户端发送剩余数据。 - 第三次挥手(FIN) :当服务端确认剩余数据都发送完毕后,也会发送 FIN,表示自己也准备关闭发送方向。该报文段同样包含一个序列号,例如
seq=y。发送后,服务端进入LAST_ACK状态,等待客户端最终确认。 - 第四次挥手(ACK) :客户端收到服务端的 FIN 后,回复最终 ACK,确认号为
ack=y+1。发送后,客户端进入TIME_WAIT状态。服务端收到这个 ACK 后进入CLOSED。客户端则在TIME_WAIT状态等待 2MSL 后,最终进入CLOSED。
注意区分:半关闭(Half-Close) 指一个方向已经发送 FIN,另一个方向仍可继续发送数据;**半开连接(Half-Open Connection)**通常指一端崩溃、重启或状态丢失后,另一端仍以为连接存在。两者不是同一个概念。
2.2TIME_WAIT 状态为什么必须等待 2MSL?
可以拆成两个"1MSL"来理解,这样更直观:
- 第一个 MSL:确保客户端发送的最后一个 ACK 报文能"走到底"。
假设 ACK 报文在网络中延迟了,只要延迟时间不超过 1MSL,服务端就能收到。如果超过 1MSL 还没到,服务端会认为 ACK 丢失,并重发 FIN 报文。
- 第二个 MSL:确保服务端重发的 FIN 报文能"回来",并让客户端有机会重新回复 ACK。
服务端重发的 FIN 报文在网络中最多存活 1MSL,客户端在 2MSL 内一定能收到这个重发的 FIN,然后重新发送 ACK------这样就覆盖了"ACK 丢失→服务端重发→客户端再确认"的完整流程。
等 2MSL 过去,有两种结果:
- 要么服务端已经收到 ACK 并关闭,网络中也不会再有本次连接的任何报文,那么客户端等2msl自然关闭;
- 要么第一个msl过去了,但是服务端没有收到ACk,那么定时任务器就会重传,传播耗时又是1MSL,然后再2MSL时间点又会向服务端发送ACK。(有点像循环,只有在2msl内没有收到重发的Fin报文段,客户端才正常关闭)
简单说,2MSL 是 TCP 为了"双向兜底"设计的:既要保证自己的 ACK 能送达,也要保证对方的重发请求能被自己处理,最终彻底清空网络中属于本次连接的所有报文,避免干扰新连接。
2.3TIME_WAIT 过多会有什么问题?如何优化?
TIME_WAIT 过多会耗尽源端口,导致无法创建新连接,也会消耗内核内存。
优化方法包括:开启 tcp_tw_reuse(重用处于 TIME_WAIT 的端口),使用长连接减少连接关闭,扩大本地端口范围,或调整架构让服务端不主动关闭连接。
3.HTTP版本区别问题
3.1HTTP/1.1、HTTP/2、HTTP/3 核心区别
| 特性 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 传输层 | TCP | TCP | UDP(QUIC) |
| 连接方式 | 每个请求一个连接(或少量并行连接) | 单一 TCP 连接,多路复用 | 单一 QUIC 连接,多路复用 |
| 队头阻塞 | 存在(应用层 + TCP 层) | 解决应用层队头阻塞,但 TCP 队头阻塞仍存在 | 彻底解决队头阻塞(流独立) |
| 头部压缩 | 无(纯文本) | HPACK(静态+动态表,有安全风险) | QPACK(改进版,适应乱序) |
| 服务端推送 | 不支持 | 支持(Server Push) | 支持(更灵活) |
| 连接建立 | TCP + TLS(可选) | TCP + TLS(至少 2-3 RTT) | QUIC 内嵌 TLS 1.3,0-1 RTT |
| 协议开销 | 较大(文本协议) | 二进制分帧,更高效 | 二进制,UDP 无连接管理 |
| 流量控制 | TCP 层面 | TCP + 流级别 | QUIC 流级别 + 连接级别 |
3.2HTTP/2 的多路复用如何解决 HTTP/1.1 的队头阻塞?
HTTP/1.1 的队头阻塞(Head-of-Line Blocking)
-
HTTP/1.1 允许多个 TCP 连接并行(通常 6-8 个),但每个连接内请求是串行的:必须等待上一个请求的响应返回才能发送下一个请求。
-
如果某个请求的响应很慢(如大图片),后续请求都会被阻塞,这就是应用层队头阻塞。
HTTP/2 的多路复用(Multiplexing)
-
在一个 TCP 连接上,同时交错发送多个请求和响应。
-
每个请求/响应被拆分为二进制帧 (Frame),每个帧带有流标识符(Stream ID)。接收端根据 stream ID 重新组装,无需按顺序。
-
因为帧可以乱序交错发送,一个慢请求的帧不会阻塞其他请求的帧,应用层队头阻塞被消除。
但 HTTP/2 仍有 TCP 层队头阻塞
- 由于所有流仍然共享同一个 TCP 连接,如果 TCP 层发生丢包,TCP 的拥塞控制会等待重传,导致整个连接的数据都暂时阻塞(即使其他流的帧已经到达)。这是 TCP 本身的队头阻塞,HTTP/2 无法解决。
HTTP/3 为什么用 QUIC 而不是 TCP?
QUIC(Quick UDP Internet Connections) 是 Google 设计的基于 UDP 的传输协议,被 IETF 标准化为 HTTP/3 的底层。
原因 1:彻底解决队头阻塞
-
QUIC 在 UDP 之上实现了多流复用,且每个流内部独立丢包重传。
-
如果一个流丢包,只影响该流,其他流可以继续前进(而 TCP 重传会阻塞所有流)。
-
这是 HTTP/3 最大的优势。
原因 2:更快的连接建立(0-RTT)
-
TCP 需要三次握手(1 RTT),TLS 1.3 需要额外 1 RTT(或 0-RTT 恢复)。
-
QUIC 将 TLS 1.3 嵌入传输层,首次连接只需 1 RTT,后续连接可实现 0-RTT(直接发送数据),大幅降低延迟。
原因 3:连接迁移(Connection Migration)
-
TCP 连接由(源 IP,源端口,目标 IP,目标端口)四元组标识。当客户端 IP 变化(如从 WiFi 切换到移动网络),TCP 连接必须重新建立。
-
QUIC 使用 连接 ID(Connection ID) 标识连接,不依赖 IP/端口。即使客户端 IP 变化,只需发送带有相同连接 ID 的包,连接即可继续,无需重新握手。
原因 4:更好的拥塞控制和流量控制
-
QUIC 在用户空间实现拥塞控制,可以更快迭代算法(如 BBR、CUBIC),不依赖操作系统内核。
-
提供流级别和连接级别的流量控制,更灵活。
原因 5:避免 TCP 协议僵化(Protocol Ossification)
-
TCP 是内核实现的,新功能难以部署(例如增加新 TCP 选项会被中间设备丢弃)。
-
QUIC 在用户空间实现(通常使用 UDP),易于更新和实验,且 UDP 对中间设备透明。
缺点
-
UDP 可能被防火墙或 NAT 限制(但现代网络基本支持)。
-
用户空间协议栈可能比内核 TCP 稍慢(但硬件加速可缓解)。
4.HTTPS 的 TLS 1.2 握手过程是怎样的?
TLS 1.2 握手: 1. Client Hello → 客户端发送支持的 TLS 版本、密码套件列表、随机数 2. Server Hello → 服务端选定密码套件、发证书(公钥)、服务端随机数
-
Client 验证证书 → 生成预主密钥(Pre-master secret),用服务端公钥加密传输
-
双方各自计算会话密钥(对称密钥,用于后续加密通信)
-
Finished 消息 → 之后所有数据都用对称加密传输
对称加密和非对称加密发生在哪个阶段
| 加密类型 | 作用阶段 | 用途 |
|---|---|---|
| 非对称加密(RSA/ECDSA) | 握手阶段的 密钥交换 | 安全传输 Pre-Master Secret(RSA),或用于数字签名(ECDHE 的签名验证)以及证书验证。非对称加密保证只有合法的接收方能获取 Pre-Master Secret。 |
| 对称加密(AES/ChaCha20) | 握手完成后的 数据传输阶段 | 使用从 Pre-Master Secret、Client Random、Server Random 计算出的 会话密钥,对所有应用数据进行加密和解密。对称加密速度快,适合大数据量。 |
TLS 1.3 相比 1.2 有哪些改进?
握手缩短到 1 RTT(支持 0-RTT),强制前向安全(仅允许 ECDHE/DHE),移除了不安全算法,加密更多握手消息,协议更简洁高效。这些改进让 TLS 1.3 更快、更安全。"
5.GET 和 POST 的区别是什么?
5.1语义层面
| 维度 | GET | POST |
|---|---|---|
| 目的 | 从服务器获取资源(只读) | 向服务器提交数据(创建/修改资源) |
| 参数传递 | URL 查询字符串(?key=value) |
请求体(body)中 |
| 长度限制 | 受浏览器/服务器 URL 长度限制(通常 2KB~8KB) | 理论上无限制(受服务器配置和内存限制) |
| 书签/历史 | 可以被收藏、缓存,保留在浏览器历史 | 通常不能被收藏或缓存 |
| 浏览器后退/刷新 | 无影响(幂等) | 会提示重新提交表单 |
5.2从幂等性角度
-
幂等:多次执行相同请求,对资源的状态影响一致,且结果相同。
-
GET :是幂等 的。连续多次 GET 同一个 URL,返回的资源内容可能变化(如新闻更新),但不会对服务器资源产生副作用(不修改数据)。
例子:
GET /user/123无论执行多少次,都不会新建用户或修改用户信息。 -
POST :不是幂等 的。连续多次 POST 相同数据可能会创建多个资源。
例子:
POST /orders提交订单,执行两次会创建两个订单(除非服务器去重)。
注意:HTTP 协议规定 GET 应为安全且幂等的,但实际开发中不应在 GET 接口中实现修改操作。
5.3从缓存角度
-
GET :响应可以被浏览器、CDN、代理服务器缓存 。缓存策略由
Cache-Control、Expires等头控制。适合获取静态资源、公共数据。
-
POST :响应默认不被缓存 (除非响应头明确允许
Cache-Control: public等,但很少见)。因为 POST 通常用于提交数据,结果不应该被复用。
如果 POST 返回的资源是可缓存的,必须设置合适的缓存头,但实践中极少这样做。
5.4从安全性角度
1. 传输安全性
-
GET 参数暴露在 URL 中(浏览器历史、服务器日志、Referer 头、地址栏可见)。
-
POST 参数在请求体中,不会直接显示在 URL 上,但并不加密(除非使用 HTTPS)。
所以 :两者都不安全(明文传输)。使用 HTTPS 可以同时保护 URL 路径和请求体,但请注意:HTTPS 下 URL 的参数仍然可能暴露?
- 实际上 HTTPS 加密整个 HTTP 报文,包括 URL 和请求体。但 URL 可能出现在浏览器历史、书签、服务器日志中(解密后),而 POST 体不会出现在这些地方,相对更隐蔽。
6.SQL 注入、XSS、CSRF 分别针对什么目标?
一、SQL 注入(SQL Injection)
针对目标:数据库
攻击原理 :
攻击者通过在用户输入(如表单、URL 参数、Cookie)中插入恶意的 SQL 代码,欺骗后端应用程序将其拼接到 SQL 查询语句中,从而执行非预期的数据库操作。
典型后果:
-
绕过登录验证(
' OR '1'='1) -
窃取敏感数据(如用户表、密码)
-
修改或删除数据(
DROP TABLE) -
执行数据库管理操作(如 shutdown)
防御:
-
使用参数化查询(PreparedStatement)或 ORM 框架
-
对输入进行严格过滤/转义
-
最小权限数据库账户
二、XSS(跨站脚本攻击,Cross-Site Scripting)
针对目标:浏览器 → 最终用户
攻击原理 :
攻击者将恶意脚本(通常是 JavaScript)注入到网页中,当其他用户浏览该页面时,脚本会在其浏览器中执行。由于脚本来自"可信"的网站,可以访问用户的 Cookie、会话令牌、DOM 等。
三种类型:
-
反射型 XSS:恶意脚本通过 URL 参数传递,服务器直接返回该脚本。
-
存储型 XSS:恶意脚本被存储到服务器数据库(如评论区),然后永久展示给其他用户。
-
DOM 型 XSS:完全在前端由 DOM 操作注入。
典型后果:
-
窃取用户 Cookie(包括 session ID)
-
发起恶意请求(如盗用身份发帖、转账)
-
键盘记录、钓鱼弹窗
防御:
-
对输出进行 HTML 转义(如
<→<) -
使用 Content Security Policy(CSP)限制脚本来源
-
设置 Cookie 的
HttpOnly和Secure标志,防止 JS 读取
三、CSRF(跨站请求伪造,Cross-Site Request Forgery)
针对目标:用户已认证的会话(Web 应用的操作接口)
攻击原理 :
攻击者诱导已登录某网站(如银行、社交网络)的用户点击一个恶意链接或访问一个恶意网站,该网站会向目标网站发起伪造的请求(如转账、修改密码)。浏览器会自动携带该网站的用户 Cookie(认证凭证),服务器无法区分该请求是用户主动发起还是伪造的。
典型后果:
-
在用户不知情的情况下执行资金转账、修改个人资料、发布内容等操作。
-
只针对有状态会话(Cookie 认证),对 JWT(放在 Header 中)一般无效(除非存储不当)。
防御:
-
CSRF Token:表单或请求头中加入随机 Token,服务器验证。
-
SameSite Cookie 属性 :设置为
Strict或Lax,阻止跨站请求携带 Cookie。 -
验证 Referer / Origin 头(较弱)。
-
二次验证:如支付时要求输入密码或验证码。
对比总结表
| 攻击类型 | 针对目标 | 关键原理 | 常见后果 | 主要防御 |
|---|---|---|---|---|
| SQL 注入 | 数据库 | 拼装 SQL 查询,执行恶意代码 | 数据泄露、篡改、删除 | 参数化查询,输入过滤 |
| XSS | 浏览器/用户 | 注入恶意脚本到网页,在用户浏览器执行 | 盗取 Cookie、会话劫持、钓鱼 | 输出转义,CSP,HttpOnly |
| CSRF | 用户认证会话 | 伪造跨站请求,利用已认证的 Cookie | 执行非预期操作(转账、改信息) | CSRF Token,SameSite,验证 Referer |
这里再说一下最危险的CSRF跨站脚本请求伪造的解决办法:
CSRF 防御:
-
CSRF Token:表单中嵌入随机 token,服务端校验(最常用)
-
SameSite Cookie:设置 SameSite=Strict/Lax,跨站请求不发送 Cookie
-
Referer/Origin 校验:验证请求来源域名
面试回答逐字稿
"SQL 注入、XSS 和 CSRF 是三种常见的 Web 安全漏洞,它们针对的目标和攻击方式不同:
SQL 注入 :针对数据库。攻击者通过输入恶意 SQL 代码,欺骗后端应用执行非预期的数据库操作,从而窃取或破坏数据。防御的核心是使用参数化查询。
XSS(跨站脚本攻击) :针对浏览器和最终用户。攻击者向网页中注入恶意脚本,当其他用户访问时,脚本在用户浏览器中执行,可以盗取 Cookie、劫持会话等。防御包括输出转义和 Content Security Policy。
CSRF(跨站请求伪造) :针对用户已认证的会话(即 Web 应用的操作接口)。攻击者诱导用户访问恶意网站,利用浏览器自动携带目标网站的 Cookie,伪造用户身份发起请求(如转账、修改密码)。防御主要靠 CSRF Token 和 SameSite Cookie 属性。
这三种攻击分别从数据层、前端层、会话层威胁 Web 应用,需要针对性地组合防御手段。"