你花了三个月把服务上线,自测「一切正常」。而在世界的某个角落,一台服务器正用一个 30,000 人维护的漏洞模板库,对着你的域名做每秒数千次的探测。它不在乎你的系统「看起来安全」,它只在乎你的接口响应了什么。
很多做后端开发的人对「Web 安全」的认知是零散的:知道 SQL 注入要预防、知道密码要加密。但攻击者不是按知识点进攻的,他们按攻击链进攻。今天我们把 Web 安全从「漏洞清单」升级成「攻击链思维」,结合 Java 后端的真实案例,给你一张完整的攻防地图。
一、OWASP Top 10:一张「10 年不衰」的漏洞榜单
OWASP(开放式 Web 应用程序安全项目)每 3-4 年发布一次 Web 应用 Top 10 风险。2021 版至今仍是 Web 领域事实标准,2025-2026 年 OWASP 的重点则转向了大模型应用(LLM Top 10,前一篇讲过)。2021 版十个大类:
| 2021 排名 | 风险类别 | 一句话解释 |
|---|---|---|
| A01 | 访问控制失效 | 越权访问:普通用户拿到管理员接口 |
| A02 | 加密失败 | 明文传输、弱算法、密钥硬编码 |
| A03 | 注入 | SQL、命令、XSS……用户输入当代码执行 |
| A04 | 不安全设计 | 架构层面就没防住(没有威胁建模) |
| A05 | 安全配置错误 | 默认口令、多余端口、未锁调试接口 |
| A06 | 易受攻击和过时的组件 | Log4Shell、老版本框架(最常中招) |
| A07 | 身份识别和认证失败 | 弱密码、会话固定、暴力破解 |
| A08 | 软件和数据完整性失败 | 反序列化、CI/CD 投毒、自动更新劫持 |
| A09 | 安全日志和监控失败 | 被打了三年才发现不了 |
| A10 | 服务端请求伪造(SSRF) | 服务器帮你访问内网 |
注意 A06——「易受攻击和过时的组件」连续多年进入前三。对 Java 后端来说,这就是你我的日常:依赖树里一个没人注意的旧 jar,就是整个系统的突破口。
二、攻击链:漏洞不是孤立存在的
攻击者不会只用一个漏洞。一条典型的 Web 攻击链长这样:
1 | 侦察 → 指纹识别 → 入口获取 → 权限提升 → 横向移动 → 数据落地 |
第一步:侦察(不碰你的系统,先了解你)
- 搜索引擎语法:
site:yourdomain.com、inurl:admin、filetype:sql; - 子域名枚举:找出你忘了保护的
.test.、.staging.、.dev.子域; - GitHub/代码托管搜索:搜到你硬编码的密钥(很多公司把数据库密码提交到了仓库);
- 证书透明度日志:枚举你的所有域名和子域。
第二步:指纹识别
自动化工具一发请求就能知道:你的 Web 容器是 Tomcat 还是 Jetty?框架是 Spring Boot 哪个版本?反代是 Nginx 还是 OpenResty?版本号一旦确定,对应的 CVE 列表就到手了。
第三步:入口获取
指纹之后挑软柿子捏。对 Java 后端,经典入口有三条:
入口一:Log4Shell(CVE-2021-44228)
日志库 Log4j2 的 JNDI 注入漏洞——只要用户输入被记入日志,${jndi:ldap://...} 就能远程加载恶意类。你之前读过 《Log4Shell:一次震动全球 Java 生态的”完美漏洞”》,它被称为「2010 年代 Java 生态最大的漏洞」不是没道理的:修复了一版还有第二版(CVE-2021-45046),全球拖了一年才真正收尾。
入口二:反序列化
Java 的 ObjectInputStream 反序列化用户数据,等于把攻击者的「类字节码执行许可」直接放进内存。从 WebLogic 的 T3 协议、Fastjson 的 autoType,到 Shiro 的 rememberMe 默认密钥,这个家族的共同悲剧是:厂商修一次,绕过一次——因为「反序列化不可信数据」这个设计缺陷从一开始就注定了。
入口三:Spring 家族
Spring 的 SpEL 表达式注入、actuator 端点暴露(/actuator/env 直接读环境变量、/actuator/heapdump 下载堆内存文件)、Spring4Shell(CVE-2022-22965,通过 Web 参数触发的 RCE)——Spring 生态每年都在贡献新 CVE,而「框架默认配置直接上线」的公司永远是重灾区。
第四步:权限提升
拿到 RCE 只是开始。攻击者要的是管理员权限:
- 提权:内核漏洞、SUID 提权、配置错误;
- 越权:
/admin接口没鉴权,或者改了userId参数就是别人账户(A01 访问控制失效——最常见的实战漏洞,几乎每个站都有); - 凭证复用:数据库里解密出明文密码,拿去撞号。
第五步:横向移动
从你的应用服务器,攻击者开始「走内网」:SSH 弱口令(你读过的 《SSH 安全全景》 讲过爆破)、内网 SMB、数据库直连、云元数据接口(169.254.169.254)。SSRF 在这里大显身手——你的服务器帮他访问内网,他自己根本不需要进入内网。
第六步:数据落地
最后,打包数据、加密压缩、按流量伪装(HTTPS、CDN、图片隐写)外传。等你的 SOC 发现,数据早到了暗网。
SSRF 为什么是「攻击链的放大器」:深挖 A10
在第五步”横向移动”里,SSRF(服务端请求伪造)扮演了关键角色,这里把它单独挖深一层,因为它是最容易被后端开发者低估的漏洞:
本质:SSRF 不是”攻击你的服务器”,而是**”借你的服务器去攻击别人”**。当你的应用有一个”服务器主动去请求某个 URL”的功能(比如”上传图片时抓取远程图片””webhook 回调””PDF 导出抓取网页”),攻击者就可以把 URL 指向内网地址,让你的服务器替他”访问”内网。
云时代的放大效应:在云环境里,SSRF 的价值被放大了几十倍——因为云服务器上有一个”元数据服务”(
169.254.169.254),里面存着这台服务器的云账号临时密钥。攻击者通过 SSRF 让服务器访问这个地址,就能拿到密钥,进而控制整个云账号下的所有资源。一次 SSRF,从”单台服务器”升级为”整个云账号失守”。防不住的根因:SSRF 难防,是因为”服务器访问外部 URL”这个功能本身是合法需求——你不能因为怕 SSRF 就砍掉所有”抓取远程内容”的功能。正确的做法是精细化管控:URL 白名单(只允许特定域名)、禁用内网地址段(
127.0.0.1、169.254.169.254、10.x、192.168.x)、DNS 重绑防护(防止”域名解析到外网 IP,实际连接时重定向到内网”)。
SSRF 在 OWASP 2021 里被单独列为 A10,恰恰说明它的地位:它不是一个”独立的漏洞”,而是”把其他漏洞串联起来、把单点攻击放大成整网失守”的放大器。 在一条完整的攻击链里,SSRF 往往是从”应用层”跳到”内网层”的那块跳板。
一条真实攻击链的完整复盘
光讲六步太抽象,我们把它串成一条完整的真实攻击链来看。假设攻击者盯上了一个普通的 Java 电商后端:
- 侦察:先用
site:target.com filetype:sql搜到一条备份数据库的下载链接(管理员随手放的backup.sql),同时用子域名枚举发现了.staging.target.com(测试环境)。 - 指纹:访问
.staging返回了X-Powered-By: Servlet/3.0和 Spring Boot 的默认错误页,/actuator未鉴权直接暴露——版本号Spring Boot 2.1.0对应一串已知 CVE。 - 入口:测试环境的依赖里有个老版本的 Fastjson,攻击者用反序列化 payload 打进去,拿到一个低权限 shell。
- 提权:在
/actuator/env里读到了明文数据库密码,又发现/admin接口改了userId参数就能越权查任意用户订单。 - 横向:用数据库账号尝试 SSH 登录内网其他机器,再用 SSRF 让应用服务器访问云元数据接口
169.254.169.254,拿到了云账号的临时密钥。 - 落地:把整个订单库、用户表打包,伪装成图片流量分片外传。
你会发现:这条链里没有任何一步是「高深技术」,每一步都是「配置错误 + 过时组件 + 越权」的叠加。攻击者不靠一个惊天 0day,靠的是你攻击链上每一环都松一点点。
攻击链的「木桶效应」:最弱的一环决定结局
复盘完这条攻击链,有一个必须点破的规律——攻击链遵循严格的”木桶效应”,而防御方恰恰相反:攻击者只找最弱的一环,防御者却要守住每一环。
- 攻击者是”单点突破”:他不需要攻破你的防火墙、WAF、数据库、云账号”全部”,他只需要找到其中最弱的一环(比如测试环境那个老 Fastjson),从这一点撕开口子,然后一路横向。
- 防御者是”全面设防”:你必须保证侦察、入口、提权、横向、数据落地每一环都有阻力——因为任何一环”松了”,攻击者就会从这里进来。
- 这造成了天然的不对称:攻击者投入 1 分精力,只需要命中你 100 个弱点中的 1 个;防御者投入 100 分精力,却要守住全部 100 个弱点。
这就是为什么”Web 安全”这么难,也为什么”纵深防御”(后面第六节)是唯一正确的姿势——你不可能让每一环都”绝对安全”,但你可以让每一环都”不那么好攻”,从而让整条链的突破成本,高到攻击者觉得”不划算”。 攻击者也是讲投入产出比的,他更愿意去挑那个”一环都不设防”的软柿子。
三、自动化武器库:攻击者的「十万天兵」
手工测漏洞早已过时。现代攻击者靠自动化工具链流水线作业。核心武器如下:
| 工具 | 类型 | 说明 |
|---|---|---|
| Burp Suite | 抓包/手工测试 | Web 安全测试的「瑞士军刀」,业界标配 |
| OWASP ZAP | 开源扫描器 | 免费开源的 Web 漏洞扫描,OWASP 出品 |
| sqlmap | SQL 注入 | 自动化检测+利用 SQL 注入 |
| ffuf | 目录/参数爆破 | 高速模糊测试,爆破隐藏路径和参数 |
| Nuclei | 漏洞扫描器 | 模板化扫描,30.8k star 的开源之王 |
Nuclei:社区驱动的「漏洞雷达」
Nuclei(github.com/projectdiscovery/nuclei,30.9k star,MIT 协议)是近五年 Web 安全领域最重要的开源项目之一,README 核心信息:
- YAML 模板:每个漏洞检测规则就是一个 YAML 文件,全球数千名安全研究员持续贡献模板——新 CVE 披露后,几小时内就有对应检测模板;
- 多协议支持:HTTP/HTTPS、TCP、DNS、SSL、WebSocket、WHOIS、文件、代码执行检测等;
- 零误报设计:模板模拟真实攻击步骤,比传统扫描器误报率低得多;
- CI/CD 集成:可直接接入流水线做漏洞回归测试;
- 带外检测(OAST):内置 Interactsh 交互服务,检测 SSRF、盲注等无法直接从响应判断的漏洞;
- Headless 浏览器:可检测前端 JS 类漏洞;
- 资产发现:集成 Shodan、Censys、Fofa 等引擎,做攻击面测绘;
- AI 模板生成:支持用 AI 提示词自动生成检测模板(
-ai参数)。
一个例子:Log4Shell 爆出当天,Nuclei 模板库就有了检测规则——探测速度比大部分企业的应急响应还快。这就是攻防不对等的根源:攻击者的工具每天都在更新,而你的依赖每周都在变旧。
其他重要工具(补充武器库)
除了上面五件,攻击链的不同环节还各有专用工具,拼起来才是完整的「工具箱」:
| 工具 | 环节 | 一句话说明 |
|---|---|---|
| Amass / subfinder | 侦察 | 子域名枚举,找出被遗忘的攻击面 |
| nuclei + Interactsh | 探测 | 带外检测(OAST),抓 SSRF、盲注这类「看不见响应」的洞 |
| gobuster / dirsearch | 侦察 | 目录爆破,找隐藏路径、备份文件 |
| Metasploit | 全链路 | 模块化的漏洞利用框架,覆盖从入口到提权 |
| Responder / impacket | 横向 | 内网凭证窃取、SMB 中继,攻击链后段专用 |
把这些工具和前面五件组合起来,你就能理解「自动化攻击」的真实含义:攻击者不是一个人拿着一把刀,而是一条流水线,每个环节都有一台专用的机器。
四、把攻击链翻译成防御清单
| 攻击链阶段 | 攻击者动作 | 防御动作 |
|---|---|---|
| 侦察 | 子域枚举、源码搜密钥 | 收紧子域、密钥扫描(gitleaks/trufflehog)、最小暴露面 |
| 指纹 | 探测版本 | 隐藏版本号、及时升级、WAF 规则 |
| 入口 | Log4Shell/反序列化/Spring 漏洞 | 依赖升级、禁止反序列化不可信数据、白名单 |
| 提权 | 越权、撞库 | 全站鉴权+授权校验(不信任前端)、密码哈希、MFA |
| 横向 | SSRF、内网爆破 | 网络分段、出站流量管控、元数据接口防护 |
| 数据 | 打包外传 | DLP、数据加密、日志监控(A09) |
五、给 Java 后端开发者的五条底线
- 依赖升级是安全工作,不是运维杂活:A06 漏洞组件连续霸榜,
npm audit/mvn dependency-check要进 CI。 - 永远不反序列化不可信数据:你的反序列化入口就是攻击者的 RCE 入口(反序列化三连都是血的教训)。
- 默认最小权限:
actuator不暴露公网、管理接口独立网络段、账号按需授权。 - SSRF 防护是标配:任何「服务器请求外部 URL」的功能(图片代理、webhook、PDF 导出)都要做 URL 白名单 + DNS 重绑防护。
- 假设你已经被扫描:部署前跑一遍 Nuclei + ZAP,把你的攻击面在地图上标出来——黑客不会等你测完再动手。
五·补充:一张「上线下线」自查表
把上面的攻击链翻译成上线前可以直接打勾的检查项,比抽象建议更有用:
| 检查项 | 具体动作 | 对应攻击链环节 |
|---|---|---|
| 依赖体检 | mvn dependency-check + npm audit 无高危,老 jar 要么升要么隔离 |
入口 |
| 反序列化入口排查 | 全局搜索 ObjectInputStream、Fastjson parseObject、Shiro 配置,能关则关 |
入口 |
| Actuator 关闭 | 生产环境 management.endpoints.web.exposure.include 设为空或只留 health |
提权 |
| 越权测试 | 用低权限账号调一遍所有「按 id 查数据」的接口,验证 userId 是否可信 |
提权 |
| SSRF 白名单 | 图片代理/webhook 的 URL 只允许域名白名单,禁 169.254.169.254、127.0.0.1 |
横向 |
| 日志开启 | 登录、越权、异常请求都有日志,且接入告警(A09) | 数据 |
| 出站管控 | 服务器出站流量最小化,异常大流量告警 | 数据 |
这张表的价值在于:它把「安全」从玄学变成了可以逐项打勾的工程动作。上线前花半小时过一遍,就能挡住前面那条真实攻击链里的大部分环节。
六、防御纵深:为什么「一层防御」永远不够
讲完攻击链,再看防御的正确姿势。很多人以为「上了 WAF 就安全了」,这是一个危险的误解——WAF 只是防御纵深里的一层,不是全部。
一个健康的防御体系,应该是「纵深防御」(Defense in Depth):在攻击链的每一环都设防,而不是指望某一道墙挡住一切。
1 | 攻击链:侦察 → 指纹 → 入口 → 提权 → 横向 → 数据 |
这套纵深防御的关键逻辑:
- 侦察层:收紧子域名、不把测试环境暴露公网、密钥扫描进 CI——让攻击者「看不见你」。
- 入口层:WAF 挡住已知攻击特征 + 依赖升级堵住已知漏洞——两道防线叠加,因为 WAF 会被绕过,依赖升级也有空窗期。
- 提权层:全站鉴权 + 越权测试 + 最小权限——假设攻击者已经进来,让他「动不了」。
- 横向层:网络分段、出站管控、SSRF 白名单——假设他拿到一台机器,让他「出不去」。
- 数据层:DLP、加密、日志告警——假设数据要外传,让你「看得见、拦得住」。
一句话:攻击者不在乎你「有没有漏洞」,只在乎「哪一环松」。同理,防御者也不该追求「某一道墙牢不可破」,而应该让每一环都有阻力,让整条链的突破成本高到不划算。对个人开发者来说,前面那张「上线下线自查表」就是纵深防御的最小实现。
辨析:为什么「上了 WAF」不等于「安全了」
这里要把一个流传很广的误解掰开——很多开发者以为”上了 WAF 就万事大吉”,这恰恰是最危险的心态:
- WAF 只能挡”已知的、有特征的”攻击:WAF 靠规则匹配攻击特征(比如识别 SQL 注入的
' OR 1=1)。但攻击者可以用编码绕过(URL 编码、双重编码、Unicode 混淆)、分块传输、参数污染等方式,把攻击”变形”到 WAF 认不出。 - WAF 挡不住”逻辑漏洞”:越权(改
userId看别人数据)、SSRF、业务逻辑缺陷,这些没有”恶意特征”可言——一个”正常”的 HTTP 请求,WAF 凭什么拦?WAF 擅长拦”看起来像攻击的”,拦不住”看起来很正常、但逻辑上越权”的。 - WAF 本身也会成为攻击面:WAF 是部署在最前面的组件,它自己若有漏洞(历史上发生过多次 WAF 被绕过、被 RCE 的事件),反而成了攻击者的”第一块跳板”。
所以正确的认知是:WAF 是”纵深防御里的一层”,不是”安全的终点”。 它就像小区门口的保安——能拦住”形迹可疑的陌生人”,但拦不住”拿着你门禁卡、走路正常的熟人”。真正的安全,还得靠门禁(鉴权)、监控(日志)、防盗门(依赖升级)各司其职。
七、一句话总结
Web 安全的本质是攻击链对抗:攻击者不在乎你「没有高危漏洞」,只在乎你的攻击链上有没有一环是松的。对个人开发者,守住「依赖升级 + 反序列化红线 + 鉴权校验 + SSRF 防护」四条底线,就已经挡住了 80% 的自动化攻击;剩下的 20%,交给日志监控和应急响应去兜底。
最后补一句给后端同学的自省:安全不是”上线前测一次”的仪式,而是”每天都在发生”的对抗。 你今天部署的每一个接口,此刻都正在被全世界的自动化扫描器探测。与其祈祷”没被发现”,不如假设”已经被发现”——然后按本文的攻击链,一环一环地,把自己代入攻击者的视角,去审视自己的系统。
素材来源
- Nuclei 官方仓库 README(github.com/projectdiscovery/nuclei):30.9k star;MIT 协议;YAML 模板驱动;数千社区贡献者;支持 HTTP/TCP/DNS/SSL/WebSocket/WHOIS/Headless 等协议;内置 Interactsh 带外检测(OAST);可接入 CI/CD。
- OWASP Top 10(2021)官方分类:A01-A10 条目为公开标准。
- Log4Shell(CVE-2021-44228 / CVE-2021-45046)、Spring4Shell(CVE-2022-22965)、Java 反序列化系列:与本站已有文章交叉引用。
- 攻击链方法论(侦察→指纹→入口→提权→横向→数据):业界通用框架(MITRE ATT&CK 与渗透测试实战经验综合)。
评论