文章总结: 本文分享了腾讯云SAST工具XCheck的落地实践,详述了如何通过自研平台解决审计继承与场景区分难题。通过集成AI实现误报精准识别与修复建议生成,针对路径穿越漏洞进行定制优化,构建了AI降噪率等指标体系。尽管面临准确率下降与重复报警挑战,仍实现了DevSecOps全流程自动化。未来规划利用AI提升检出能力与实现代码一键修复。 综合评分: 90 文章分类: 安全建设,应用安全,安全运营
腾讯云SAST Xcheck落地实践
原创
楼兰2333
楼兰学习网络安全
2025年12月30日 19:45 北京
一、背景
2024年8月,我很认真很客观的从很多款商业产品选择了腾讯云的xcheck
选择xcheck的几个关键因素:
① 在检测引擎方面,不需要编译,平均扫描速度30秒,POC阶段的准确率:84.54%、召回率:80.00%,可扩展性强;
② 在产品层面,这是我见过设计的最好的产品之一,对运营工作非常友好;
③ 在API层面,适配我们对自动化运营流程的规划,可以拿到所需的数据。
2025年5月,完成了SAST存量漏洞的全部复核(未走专项,边复核边通过安全工单推动修复);这个阶段我得到了一份非常宝贵的数据:存量治理阶段的准确率:67.20%,以及各漏洞类型的准确率,下文中的一些措施便是基于这些数据做的决策。
2024年10月~2025年4月:人力全部在支持基础反入侵领域的工作,SAST进度完全停滞。
2025年7月,完成了SAST自动化流程落地,包括流水线自动触发扫描、AI研判、自动关闭工单、AI生成修复建议。
我们公司只有我一个应用安全。
二、目标
支持线上分支全量扫描、研发自助扫描、DevOps流水线自动触发扫描;
支持自动创建漏洞工单;
支持自动复查自动关闭工单。
三、安全标准
3.1 漏洞判定标准
在xcheck中,同一组source跟sink,中间可能因为控制流涉及多条数据流,xcheck会认为是多个漏洞;
出于简单考虑,不做额外处理,以xcheck认定的漏洞作为漏洞总量。
3.2 工单聚合标准
按照工程与漏洞类型聚合为一个工单,示例:crmapi工程存在SQL注入漏洞
3.2 漏洞处置标准
测试环境人工判定有效的漏洞:IM机器人告警到业务研发
生产环境人工判定有效的漏洞:生成安全工单
四、业务流程
AppSec平台是我们自研的平台,其中一个定位是接收所有漏洞渠道反馈过来的漏洞,安全人员在上面做判定,对于需要整改的漏洞聚合成安全工单,发给工单平台。
五、部分细节
5.1 区分业务场景
我需要根据不同的业务场景,制定不同的处理策略。
与其他xAST产品不同的是,xcheck的设计中没有 ⌈组⌋的概念,或者说⌈项目集⌋ 的概念;其他的产品你在初次使用时,需要先创建一个 ⌈项目集⌋,然后点进去再创建具体的扫描任务。
xcheck的设计更加扁平化了,对于首次使用的人来说会更简单更容易上手。
优点是:可以更直观;缺点是:不方便区分业务场景。
于是,我利用扫描任务的名称来区分业务场景:
格式:{场景}_{代码仓库}_{project_id}_{project_name},示例:build_cn_23_crmapi
现在这是我们整个SDL流程共用的一个机制,包括SCA,目前预定义了下面几种类型
classSdlScene(Enum):
# 触发扫描动作的场景类型
SEC=”安全发起”
DEV=”研发发起”
BUILD=”流水线构建阶段”
DEPLOY=”流水线部署阶段”
BUILDTEST=”流水线构建测试阶段”
DEPLOYTEST=”流水线部署测试阶段”
BUILDPROD=”流水线构建生产阶段”
DEPLOYPROD=”流水线部署生产阶段”
DISTRIBUTION=”软件分发”
classSdlRepo(Enum):
# 代码仓库类型
CN=”国内”
SG=”国际化”
在收到扫描完成的回调时,先解析扫描任务的名称,再按照场景选择不同的处置动作。
5.2 审计状态全局继承
xcheck有一个字段bughash,是结合数据流每一跳计算出的漏洞唯一标识。
我期望的效果:我对某个bug打标后,下次再扫描出这个bug时,可以自动继承上次复核的结果。
在xcheck中,同一个代码工程,跨“扫描项目”扫描时,不能继承审计状态;下图所示,我在9158项目复核的结果,在9625扫描完成后,不会继承。
我认为是bug,但厂商不认为是,所以我通过AppSec平台实现状态继承:
在AppSec平台存储一份xcheck平台的漏洞标识跟研判结论,收到来自xcheck扫描完成后的回调数据后,对比AppSec平台的状态数据,对于已经复核过的漏洞,调用xcheck的API来设置状态。
5.3 AI研判时给AI多少信息?
这个需要做平衡,给少了可能导致AI拿不到关键信息,影响研判结果;给多了可能超出上下文,影响研判结果,也会增加成本。
我目前的做法:
把数据流中每一跳所在的函数体提取出来,每一跳只取函数体,将整个数据流组合成一个字符串外加漏洞基础描述给到AI;这极大的缩减了上下文的长度,在准确率方面也基本够用。
su18为我定制了一个工具,输入文件路径、行数,输出行数所处的函数体代码块:
https://github.com/su18/JavaMethodExtractor.git
示例:
5.4 引导AI识别误报
背景:经过AI研判后的漏洞会出现几种状态
- AI判定有效 & 人工判定有效
- AI判定有效 & 人工判定误报
- AI判定误报 & 人工判定有效
- AI判定误报 & 人工判定误报
问题:AI对漏洞的判定依据的确可以提升人工研判的效率,但是不方便衡量,前后都需要人工研判所有漏洞。
目标:通过减少需要人工研判的漏洞数量,来减少人工投入的时间。
思路:引导AI来识别误报,而不是判定是有效漏洞,让AI判定误报的准确率达到是100%。
基于这个思路,在设计提示词时,要明确如果找不到净化函数,那么判定为有效漏洞。
依据:
① 无法保证自动化程序总能拿到净化函数的代码,所以无法肯定一个漏洞不是误报;
② 拿到净化函数的代码后,工程师总能识别出误报,那么AI也能。
下面3个case用来佐证上面两个依据:
前面2个证明净化函数给到AI后,AI可以判定出误报;最后一个case证明净化函数给不到AI时,判定不出误报。
示例1:入参位置使用注解校验输入
String类型的ids参数一路“流”到了Dao层,且使用$符号解析表示直接拼接到了SQL语句中,扫描器认为此处存在SQL注入漏洞;但是控制器的入参中可以看到使用了注解的方式利用正则表达式对入参的值进行了格式校验,经过分析此处不存在漏洞;入参位置的注解我们的扫描器目前覆盖不到,所以进行了错判。
AI判定结论效果:
示例2:控制流的输入校验
下面的样例中,扫描器判定存在任意文件读取漏洞,通过将入参的值设置为类似 ../../../../etc/passwd,读取passwd文件;#100行对入参clusterName进行输入校验,实际没有漏洞;但是语义分析后的数据流不会包含黄色框中的部分,会直接认为#97行的clusterName直接传递到了#104行。
AI判定效果:
示例3:污点来源被重写
下面这个case中,#52行基于session信息对污点来源进行了重写,导致没有漏洞
Source传入#52行,跟传入#53行的函数是两条不同的数据流,我不会给到AI这个setAuth的函数体代码
5.5 加入AI研判后如何设计衡量指标
加入AI研判后,我在试运营阶段拆分出了两个指标:AI判定为误报的准确率、AI判定为有效漏洞的准确率
过去半年,每个经过AI研判的漏洞我都会进行二次研判,AI判定为误报的准确率可以始终保持在100%;
现在,我可以认为AI判定为误报的漏洞不需要再二次研判,肯定是误报
基于AI判定误报的准确率是100%的前提,设计如下三个指标:
三个指标的意义:
扫描器原生的准确率:用来体现扫描器原生规则的准确率,利用趋势图可以体现原生规则策略运营的效果。
AI研判降噪率:用来体现AI加持后工程师节省的时间比例,之前工程师需要研判100个漏洞,加持后只需要研判80个漏洞。
AI加持后扫描器的准确率:用来体现当前扫描器整体的准确率,通过趋势图跟原生的准确率可以体现对AI研判流程运营的效果。
注意:分母中的所有漏洞不要用历史总量,要限定时间窗口,比如过去90天,Q4季度;可以更真实的评估特定周期内的工作成果。
在做这份总结时,我用新的公式去重新计算了Q4季度xcheck的准确率,我发现低的可怜!低的可怜!只有5%!
原因:
① 非标方案的加固xcheck识别不到:
起初,识别出的大部分漏洞是标准写法;存量治理阶段结束后,会出现大量漏洞使用了非标方案进行修复,例如在控制流进行输入校验、变量重写等;会导致xcheck重新识别到时,认为还存在漏洞。
非标方案的加固case,有很多无法在xcheck上通过扩展净化器的规则来排除,因为不支持。
② 漏洞去重机制的缺陷:
对漏洞打标后,预期内下次应该自动继承标记,不再出现;但是xcheck在计算漏洞hash时,综合了数据流的每一跳还有行数,研发更新代码的频率比我想象中的高,整个数据流中只要其中一条的位置发生了改变,就会认为是一个新的漏洞。
示例:
今天:某个工程, 有20个漏洞,10个有效漏洞,用了非标方案做了加固,10个无效漏洞;漏洞总量是20,有效漏洞是10。
下周:同一个工程发版影响了数据流,非标方案加固的10个漏洞认为是新漏洞;这时漏洞总量是30,有效漏洞是10。
下下周:同一个工程发版影响了数据流,非标方案加固的10个漏洞认为是新漏洞;这时漏洞总量是40,有效漏洞是10。
你推动修复的漏洞越多、时间越久、准确率会越低。
这个问题的解决方案在最后面的规划部分有体现。
5.6 如何调试xcheck规则
腾讯云XCheck扫描器提供了一个在线的调试控制台,这是我用过最好的SAST调试控制台。
为了引流,我不在此处详细展示,请去我的知识星球看:
《腾讯云SAST XCheck调试规则》 https://articles.zsxq.com/id_hx8a0sk506at.html
5.7 关于路径穿越漏洞
1、在默认规则中删除“路径穿越”:
XCheck默认的规则中包含一个“路径穿越”类型,共四个漏洞类型“路径穿越、任意文件读取、任意文件写入、任意文件删除”;我将“路径穿越”类型做了删除,原因是:① 这个类型缺少后续读、写、删的动作时,没有实际的危害,不需要关注 ② 如果有后续动作,那么在任意文件读取/写入/删除漏洞中也会有体现,属于重复体现了。
举例:xcheck认为 污点来源传入newFile = new File(sink)中就存在路径穿越漏洞,其实这个没有任何实际危害,只有后续这个newFile变量继续执行删除等动作,才会有危害。
2、在AppSec平台聚合为路径穿越
任意文件删除/读取/上传这几种漏洞的行为特征一模一样,所以我在AppSec平台中,合并成一种漏洞类型“路径穿越”,在指标计算、研判上统一看待。
3、为路径穿越漏洞定制单独的AI研判机器人
存量治理阶段得出“路径穿越”漏洞的准确率是20.23%,是准确率最低的类型,也很合理,业内的SAST产品对路径穿越漏洞的准确率向来都很低。
为“路径穿越”漏洞定制专用的prompt,明确哪些情景判定没有漏洞,很有效的两条提示词:
① 在拼接成文件路径或者文件名时,只要在污点来源的后面拼接了其他值,那么认为没有漏洞;
② 代码中校验了文件后缀时,认为没有漏洞。
5.8 AI生成修复建议
目前,传给AI的内容跟研判时传入AI的内容一致,漏洞基础信息加数据流。
会让AI根据这些信息来总结原因、触发示例、修复代码
示例:
5.9 构建安全工单
对单个工程的全部漏洞复核完毕后,会自动触发构建安全工单的逻辑;对于有效漏洞,按照工程与漏洞类型聚合。
xcheck有一个很好的设计,支持为所有漏洞,也支持为部分漏洞创建分享链接;利用这个机制,我可以调用API为单个类型中,有效的漏洞创建分享链接。
然后再拼接AI生成的分析与修复建议:
5.10 自动关闭漏洞工单
主动自动关闭:部署阶段prod环境的线上分支没有漏洞后,自动关闭此工程对应工单。
被动自动关闭:研发将工单更新到待复查状态时,去扫描此工程线上分支及默认分支,扫描通过也自动关闭此工单。
五、26年的规划
2025年,AI在SAST方向主要体现在复核阶段协助研判、修复阶段提供修复建议;2026年,重点是利用AI来提升检出效果。
目标1:提升SAST的漏洞检出能力
运营方面:建设“检出效果提升率”,并将指标计算从线下统计转移到线上自动计算
能力方面:
① 利用AI去识别Source、Sink,覆盖所有代码仓库,将新识别的Source、Sink扩展到xcheck的规则中;
② 落地Agentic AI,作为xcheck的补充能力,让AI自己完全自主检测,自己规划-执行-检测-反馈。
目标2:提升SAST的准确率
运营方面:为准确率、降噪率等指标,构建趋势图展示,时间窗口改为90天的滑动窗口进行统计。
能力方面:
① 在AppSec平台优化XCheck漏洞去重机制,根据公司现状做平衡
② 利用subagent做AI研判,将一次研判拆分成多次研判,覆盖非数据流中的函数体
目标3:漏洞代码一键修复
存在漏洞的代码,允许研发一键修复
后话
可惜、可惜、可惜。xcheck产品后来下线了,合并到了其他产品,不会再积极更新了。
我做了一个知识星球,用来记录我对企业安全努力的痕迹,欢迎大家加入!
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:楼兰学习网络安全 楼兰2333《腾讯云SAST Xcheck落地实践》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论