Tomcat内存马原理如何为?

摘要:原理分析 | Valve —— Tomcat 特有内存马 Tomcat 特有,比 Filter 更底层、更隐蔽。 目录 一、什么是 Valve? 二、Pipeline 是什么? 三、Valve 在 Pipeline 中是&q
原理分析 | Valve —— Tomcat 特有内存马 Tomcat 特有,比 Filter 更底层、更隐蔽。 目录 一、什么是 Valve? 二、Pipeline 是什么? 三、Valve 在 Pipeline 中是"单向链表" 四、Valve 与 Filter 的关键区别 五、静态注册 Valve 六、动态注入(内存马核心) 七、Valve 的层级扩展(Engine / Host 级别注入) 八、四种内存马对比总结 总结 一、什么是 Valve? Valve 是 Tomcat Pipeline-Valve 管道机制的一部分,属于 Tomcat 特有的概念,不属于 Servlet 规范。 类比:请求处理的"高速公路收费口" 为了方便理解这几种内存马的层级关系,用高速公路来类比一下: Listener:像高速公路入口的感应线圈(车一过就记录,不干预)。 Filter:像安检闸机(可以拦车、检查、放行)。 Valve:像高速公路上的隧道阀门,位于整个系统的最底层,所有车都必须经过它,而且它可以修改车的路线甚至把车"吞掉"。 每个容器(Engine / Host / Context / Wrapper) 都有自己的 Pipeline,里面可以添加多个 Valve。 二、Pipeline 是什么? 一句话解释:Pipeline 是 Tomcat 容器内部的一个处理链,里面可以按顺序放多个 Valve(阀门),请求会像水流一样依次流过这些阀门。 每个容器实例(Engine、Host、Context、Wrapper)都有一个 Pipeline 对象,这是 Tomcat 架构的固定设计。 即使不添加任何自定义 Valve,Pipeline 也至少包含一个 基础阀门(basic),用于完成容器的核心任务(比如调用子容器、处理 Servlet)。 可以通过 pipeline.addValve(valve) 添加任意多个自定义 Valve,它们会按照添加顺序依次执行(先添加的先执行)。 请求的大致流转路径是:Engine → Host → Context → Wrapper 的 Valve 管道,最后才到 Servlet。也正因为如此,Valve 比 Filter 更早触发(在 Context 级别甚至更早),而且可以拦截所有请求(包括静态资源、404 等),不需要任何 URL 映射。 Filter、Servlet、Listener 都属于 Context 级别(即一个 Web 应用内部),而 Valve 可以加在 Engine、Host、Context、Wrapper 任意一层。 三、Valve 在 Pipeline 中是"单向链表" 请求 → [Valve A] → [Valve B] → [Valve C] → [基础阀门] → Servlet 需要注意的点: 每个 Valve 的 invoke 方法中必须调用 getNext().invoke(request, response),否则请求链会中断(后面的 Valve 和 Servlet 都不会执行)。这个和 Filter 里的 chain.doFilter(request, response) 作用一模一样。 添加过多 Valve 会影响性能,但内存马场景一般只加 1 个。 Valve 是全局生效的:添加到 Engine 的 Valve 会影响所有 Host 下的所有应用;添加到 Context 的 Valve 只影响当前 Web 应用。 拿到容器的 Pipeline 对象(通过反射获取 StandardContext、StandardHost 等),就可以直接调用 addValve() 方法,而且该方法通常是 public 的,不需要反射破解。 四、Valve 与 Filter 的关键区别 特性 Valve Filter 是否 Servlet 规范 ❌ Tomcat 特有 ✅ 规范定义 触发层级 容器级(Engine/Host/Context) 应用级(Context 内) 能否跨 Web 应用 能(Engine/Host 级别 Valve 可影响所有应用) 不能(只拦截注册的应用) 需要映射 URL 模式 否(自动全局拦截) 是(需配置 /* 等) 隐蔽性 更高(不常见于检测规则) 较高(但已是重点查杀对象) 五、静态注册 Valve 静态注册是 Tomcat 管理员配置全局功能的标准方式,不需要写任何 Java 代码(除了 Valve 实现类本身)。先搞清楚静态注册的流程,对后面理解动态注入也有帮助。
阅读全文