微服务污点分析
MScan
- 1.Introduction
- 2.Background
- 3.Challenge and Solution
- 3.1.挑战
- 3.2.解决方案
- 4.MScan
- 4.1.Entry Point识别
- 4.2.构建SDG
- 4.3.漏洞检测
- 5.Evaluation
1.Introduction
现有静态分析工具(如CodeQL)主要面向单体应用,无法有效处理微服务特有的三大挑战:1.入口点识别困难,网关(Gateway)控制哪些服务对外暴露,传统方法误将所有HTTP入口视为用户可达,导致大量误报。2.跨服务数据流追踪难:服务间通信机制多样(REST、gRPC、Kafka 等),难以准确连接发送方与接收方,导致漏报。3.上下文敏感分析开销大:微服务调用链极长,全上下文敏感分析极易因内存溢出或超时失败。针对上述问题,作者提出了MScan
2.Background

| 组件 | 作用与特点 | 示例/说明 |
|---|---|---|
| 微服务 (Microservices) | 自治、自包含的服务单元,各自独立运行于专属环境,通过明确定义的API协作实现复杂功能。 | 门户网站的登录功能由 Portal Service、Login Service 和 User Service 等多个微服务协同完成。 |
| 服务间通信 (Inter-service Communication) | 微服务之间交互的机制,支持多种协议(如 REST/HTTP、gRPC),保障松耦合与高内聚下的协同工作。 | Login 服务通过服务间通信从 User 服务获取用户数据以完成登录流程。 |
| 网关 (Gateway) | 所有外部请求的统一入口,根据路由规则将请求转发至允许访问的微服务,阻止非法直连,强化安全边界。 | 网关允许访问 Portal 和 Login 服务,但拦截直接访问 User 服务的请求,防止恶意用户越权操作。 |
下图展示了一个服务内漏洞,用户输入的恶意命令未经净化直接被执行。

下图则是一个跨服务漏洞,用户输入被 Portal Service 发送到 User Service 然后触发。

3.Challenge and Solution
3.1.挑战
挑战一:精准识别用户可达入口点(网关语义理解难)
-
问题根源:微服务通过网关统一管控外部请求,许多服务接口仅限内部调用,并非所有HTTP入口都对用户开放。
-
传统方法缺陷:单体应用分析假设“所有请求参数都是攻击源”,直接套用于微服务会导致大量误报(实验显示误报率高达60.14%)。
-
难点所在:网关配置(如Spring Cloud Gateway、Zuul)高度灵活、非结构化,规则语义复杂(例如
filter: Denied或SetResponseStatus=403表示拦截,而AddHeader不拦截),且不同网关组件差异大,难以自动化建模。
挑战二:准确建立跨服务通信链路(数据流追踪难)
-
问题根源:漏洞常跨越多个服务——污点从入口服务经消息队列(如Kafka)传递至另一服务的敏感操作。
-
传统方法缺陷:无法关联不同服务中的发送方(如
KafkaProducer.send())与接收方(如KafkaConsumer.poll()),导致漏报(实验漏报率高达54.24%)。 -
难点所在:需从海量方法调用中识别通信端点,并根据通信模式(如Kafka)和动态标识符(如
topic名)精确匹配收发双方,而实际实现方式多样且常含动态拼接逻辑。
挑战三:平衡精度与效率的污点分析(资源开销大)
-
问题根源:微服务调用链极长(多服务串联),高精度的上下文敏感分析内存与时间开销剧增。
-
传统方法困境:上下文不敏感:效率高但精度低,易误报;全上下文敏感:精度高但极易因内存溢出或超时中断(实验因OOM导致漏报率达 50.85%,CodeQL也因超时漏报)。
-
核心矛盾:如何在保障深度漏洞检测能力的同时,避免分析过程崩溃。
3.2.解决方案
1.LLM辅助识别用户可达入口点
-
核心思想:利用大语言模型(LLM)理解非结构化网关配置的语义。
-
实现方式:采用 few-shot prompting,让LLM(如 GPT-4o)判断路由规则是否允许外部访问(例如识别
SetResponseStatus=403或Denied表示拦截)。
结合静态分析提取代码中的所有API路径,仅将与“允许访问”规则匹配的路径视为真实用户入口。 -
效果:精准区分对外暴露接口与内部接口,从源头避免误报。
2.基于SDG的跨服务通信分析
-
核心思想:依据“通信模式一致”和“标识符一致”两大原则,建立跨服务数据流。
-
实现方式:基于CNCF标准,收集Kafka、gRPC、Feign等常用组件的通信API(如
send()/poll())。对通信参数(如topic名)进行反向数据流分析,解析动态拼接的值(如String.format("user/%s", op) → "user/query")。 -
图建模:将收发关系抽象为服务依赖图(SDG) 中的边,支撑跨服务污点追踪。
-
效果:准确还原污点如何从
Portal服务经Kafka流入User服务,从而发现跨服务漏洞。
4.MScan
4.1.Entry Point识别
按下面prompt提取路由规则

4.2.构建SDG
SDG的结点包括ICFG结点(对应1个程序语句)以及I-Node(表示1次跨服务通信)。每个 I-Node 包含两个关键属性:identifier - 通信的唯一标识符(如 Kafka 的 topic 名 "user/query"),确保消息正确路由。mode - 通信模式(如 Kafka、gRPC、REST),定义了使用的发送/接收API。
SDG的边集合在ICFG边基础上,新增两类关键边:(1) 服务内数据流边(Intra-service Data Flow Edge, 集合) - 刻画单个微服务内部的变量间数据依赖关系(如 a = b; 则存在 b→ab \rightarrow ab→a)。这是为跨服务污点分析提供服务内污点传播基础。(2) 跨服务通信边(Inter-service Communication Edge), 集合 ,连接不同微服务中通过同一通信实例(I-Node)交互的发送方(sender)与接收方(receiver)。sender为调用发送 API(如 kafkaProducer.send())的 ICFG 节点。Receiver为调用接收 API(如 kafkaConsumer.poll())的 ICFG 节点。当且仅当sender和receiver共享相同的 I-Node(即 identifier 和 mode 一致)时,建立边。
构建服务依赖图(SDG)的过程可分为三个核心步骤:
- 1.构造 I-Node(通信实例节点):识别通信模式(mode) - 基于CNCF标准,匹配代码中调用的通信API(如
Kafka、gRPC),确定是同步还是异步通信(mode的值为sync或者async)。解析通信标识符(identifier):对API参数进行反向数据流分析,将动态拼接的变量(如下面示例String.format("user/%s", op))还原为具体常量值(如"user/query"),确保标识符精确可匹配。目前支持的通信API如下表所示。
| Framework/Lib | Type | APIs |
|---|---|---|
| OpenFeign | Sync | @FeignClient |
| RestTemplate | Sync | RestTemplate.get, RestTemplate.post, RestTemplate.exchange |
| gRPC | Sync | *ImplBase., BlockingStub.* |
| JDK Native | Sync | URL.openConnection, HttpClient.send |
| Apache HttpClient | Sync | HttpClient.execute |
| Hutool-http | Sync | HttpUtil.get, HttpUtil.post |
| Dubbo | Sync | @DubboReference, @DubboService |
| Kafka | Async | KafkaProducer.send, KafkaConsumer.poll |
| RabbitMQ | Async | Channel.basicPublish, Channel.basicConsume |
| Redis | Async | Jedis.get, Jedis.set |
| MQTT | Async | MqttClient.publish, MqttClient.subscribe |
// Portal Service (can be accessed)
@Path(value = "/portal/query")
public User query(String id) {String op = "query";KafkaProducer kafkaProducer = new KafkaProducer(String.format("user/%s", op));kafkaProducer.send(id);...
}// User Service (can NOT be accessed)
@KafkaListener(topics="user/query")
public User queryTask() {...String id = kafkaConsumer.poll();String query = (new ScriptEngineManager()).eval(id);return select(query);
}
-
2.建立跨服务通信边:在ICFG中定位所有通信发送方(
sender)和接收方(receiver)节点。若sender与receiver具有相同的mode和identifier(即共享同一个I-Node),则在它们之间添加一条跨服务通信边,打通服务间数据流。 -
3.使用经典的IFDS算法,在每个微服务内部构建变量间的精确数据依赖关系(如 input→a→b\text{input} \rightarrow a \rightarrow binput→a→b),形成服务内污点传播路径。
4.3.漏洞检测
在微服务中,全上下文敏感分析开销过大,而完全不敏感又精度不足。MScan只对与漏洞路径(source-to-sink)相关的关键代码进行高精度分析,对无关代码降低分析粒度。关键机制是主导节点(Dominant Nodes, DN)定义为位于任意一条污点源(source)到污点汇(sink)路径上的方法调用点。这些节点直接影响漏洞是否存在,需高精度分析。对DN节点:使用最大上下文敏感度(等于最长源-汇路径长度 SmS_mSm),进行完全上下文敏感分析。对非主导节点(UN):计算其到最近DN节点的最短距离并按公式 S(n)=max(1,Smdist(n,DN2).K)S(n) = \text{max}(1, \frac{S_m}{\text{dist}(n, \text{DN}^2).K})S(n)=max(1,dist(n,DN2).KSm) 动态降低敏感度:
下图中source-sink路径为 A→B→C→DA \rightarrow B \rightarrow C \rightarrow DA→B→C→D,Sm=4S_m = 4Sm=4。节点A、B、C、D为 DN,MScan为其维护8个上下文对象(如 [A,B,C,D][A,B,C,D][A,B,C,D]),确保精确追踪。该策略将计算资源集中在安全关键路径上,在大型复杂微服务应用中显著降低内存与时间开销(避免 OOM/超时),同时保持对真实漏洞的高检出率。

最后MScan将用户可达入口点的参数(如 HTTP 请求参数)作为污点源(taint source),利用SDG中的服务内数据流边,在单个微服务内部精确追踪污点变量的传播路径。当分析遇到跨服务通信点(如 Kafka send、gRPC 调用)时,MScan通过SDG中的跨服务通信边,自动跳转到目标微服务的接收方节点。在目标服务中继续利用数据流边追踪污点,实现端到端的跨服务污点流分析。若污点数据最终流入安全敏感操作(sink,如 eval()、SQL.execute()),则报告一个漏洞。
5.Evaluation
作者基于Tai-e实现MScan,在sink规则方面,作者参考TChecker等工具设计规则,比如 <groovy.lang.GroovyShell: java.lang.Object.evaluate(String),0> 表示groovy-code injection。目前,支持8种漏洞类型,command injection, SSRF, XXE, SSTI, Groovy-code injection, SpEL injection, SQL injection, arbitrary file operations。LLM用的GPT-4o,对于sanitizer采用了CodeQL自带的PathSanitizer。RQ包括:
-
RQ1: MScan检测real-world微服务应用漏洞的效果如何?
-
RQ2: 与SOTA比较如何?
-
RQ3: MScan每个部分的贡献如何?消融实验
benchmark信息如下
TABLE 1: Breakdown of our evaluation dataset.
| Open-source Applications | Stars | LoCs |
|---|---|---|
| Apollo | 29,170 | 44,815 |
| Yudao-cloud | 16,309 | 134,585 |
| Piggymetrics | 13,258 | 3,286 |
| Mall-swarm | 11,417 | 65,933 |
| Paascloud-master | 9,796 | 25,149 |
| basemall | 8,966 | 42,571 |
| SpringBlade | 6,397 | 6,337 |
| Spring-Cloud-Platform | 6,339 | 7,554 |
| Mall4cloud | 5,732 | 27,272 |
| Pig | 5,604 | 13,071 |
| Lamp-cloud | 5,369 | 33,478 |
| Microservices-platform | 4,485 | 12,508 |
| RuoYi-Cloud-Plus | 4,303 | 41,519 |
| PassJava-Platform | 2,564 | 10,075 |
| Spring-boot-cloud | 2,121 | 5,984 |
| Youlai-mall | 2,027 | 14,065 |
| Open-mall | 1,985 | 30,540 |
| Gulimall-learning | 1,994 | 20,714 |
| SuperMarket | 1,947 | 2,821 |
| Mogu_blog_v2 | 1,572 | 26,136 |
| Light-reading-cloud | 1,277 | 3,613 |
| Novel-cloud | 1,170 | 6,154 |
| RuoYi-Cloud | 1,152 | 18,245 |
| Spring-cloud-dataflow | 1,113 | 112,630 |
| Sitewhere | 1,020 | 38,784 |
| Industrial Applications | Stars | LoCs |
|---|---|---|
| T*** | / | 84,978 |
| M*** | / | 58,387 |
| M*** | / | 35,520 |
| B*** | / | 173,155 |
| Y*** | / | 13,280 |
RQ1.检测效果
总共报告82个漏洞,经人工验证确认的59个TP,23个TP。TP覆盖:SQL注入(SQLi)、XXE、SSRF、Groovy代码注入、任意文件读写(AFW/AFR)等高危类型。影响范围包括11 个开源项目 + 2个工业级应用。开源漏洞39个,可导致数据窃取、恶意文件上传、服务器完全控制。31 个获分配 CVE(如Spring项目的CVE-2024-22263,CVSS评分8.8)。工业漏洞(20 个):均为0-day,可实现任意代码执行甚至接管整个Web服务器,严重威胁企业数据与系统安全。

误报来自于下面3类情况
| 原因 | 数量 | 说明 |
|---|---|---|
| 自定义sanitizer | 12 | 开发者实现了灵活的输入过滤逻辑,但MScan无法识别这些非标准防护措施,误报已修复路径。 |
| 不可达代码 | 9 | 静态分析未进行路径约束求解,报告了因条件不满足而实际无法触发的漏洞路径。 |
| 功能误判 | 2 | 将合法管理功能(如管理员执行任意SQL)误判为漏洞,因无法理解开发者设计意图。 |
RQ2.与SOTA比较
作者拿MScan与CodeQL进行比较,由3位资深安全研究员人工筛选CodeQL中19个与污点漏洞相关的CWE规则在相同数据集(30 个微服务应用)上运行对比。由于没有ground-truth,作者合并MScan与CodeQL报告的所有潜在漏洞。经人工验证 + PoC 复现,最终确认 59 个真实漏洞作为评估基准。
| 工具 | TP | FP | FN | precision(%) | recall(%) |
|---|---|---|---|---|---|
| MScan | 59 | 23 | 0 | 71.95 | 100 |
| CodeQL | 23 | 35 | 36 | 39.66 | 38.98 |
CodeQL误报35 个主要原因:1.忽略网关限制(21 个新增误报)- CodeQL将内部微服务接口(如 /user/**)误判为用户可达入口,而实际被网关拦截,导致报告不可利用的漏洞。2.上下文敏感度不足 - 其k-CFA策略无法精确区分深层sink的调用上下文,间接引发误报(与漏报机制相关)。
漏报36 个主要原因:1.无法处理跨服务通信(32 个)- CodeQL 完全缺失对 Kafka、gRPC 等微服务通信机制的理解,导致所有32个跨服务漏洞全部漏报。分析超时4 个 - 在大型应用中,其上下文敏感分析因超时中断,未能完成深层路径检测。
RQ3.消融实验
| 变体 | 关键改动 | TP | FP | FN | precison(%) | recall(%) |
|---|---|---|---|---|---|---|
| MScan | — | 59 | 23 | 0 | 71.95% | 100% |
| MScan-NoEntry | 禁用网关入口识别,视所有接口为用户可达 | 59 | 89 | 0 | 39.86% | 100% |
| MScan-NoSDG | 禁用 SDG,仅支持服务内分析 | 27 | 12 | 32 | 69.23% | 45.76% |
| MScan-CS | 禁用距离引导策略,使用全上下文敏感分析 | 29 | 11 | 30 | 72.50% | 49.15% |
| MScan-CS-2call | 使用固定2层上下文敏感(k=2) | 59 | 251 | 0 | 19.03% | 100% |
消融实验证明:网关感知能控制误报;SDG建模能实现跨服务检测;距离引导分析保障可扩展性与精度。
在包含30个微服务应用的数据集上,MScan完成全部分析(包括 SDG 构建 + 跨服务污点分析)共耗时8.45小时,平均每应用约16.9分钟。核心得益于其距离引导的上下文敏感策略 - 通过降低与漏洞路径无关代码的分析精度,显著减少了不必要的计算开销,从而加速整体分析过程。
[1].F. Liu et al., “Detecting Taint-Style Vulnerabilities in Microservice-Structured Web Applications,” 2025 IEEE Symposium on Security and Privacy (SP), San Francisco, CA, USA, 2025, pp. 972-990
