Atlassian老兵空降第一周:手把手教你建立可持续的安全扫描体系

最近公司来了个新同事,二十多年工作经验的前Atlassian Principal Engineer。我本以为这种级别的工程师会先开几个战略研讨会,结果人家上来就是干------直接对我们的项目跑了一遍全面安全扫描。

一周后他提交了一份报告,里面最让我震撼的不是发现了多少问题,而是他对57个高危CVE的处理方式:全部忽略,但每季度复查

这篇文章记录他做的事情,以及为什么专业的DevSecOps和新手想的不一样。

一、扫描全景:四个工具,三层防护

他用了四个开源工具对整个项目做立体扫描。第一个是Trivy,既扫文件系统又扫容器镜像。第二个是Grype,专门用来扫SBOM(软件物料清单)。第三个是ClamAV,虽然内部代码出现恶意软件的概率接近零,但他说"总得有个基线"。第四个是Semgrep,做静态代码分析。

整个扫描过程不到5分钟。Trivy跑文件系统扫描用了2分钟,镜像扫描1分半,ClamAV扫三个容器镜像总共1分24秒,Semgrep最快,1分钟搞定。

结果出来了:Backend的pip依赖里有2个高危漏洞,Frontend的npm和pnpm里各有5个中危漏洞,Dockerfile配置有4处问题,Backend容器镜像里有25个高危CVE,Frontend和Router各有1个。恶意软件扫描全部通过,105个文件,618.95MB数据,一个都没中招。

总共27个需要修复的安全问题,外加57个被标记为"可以先不管"的高危CVE

这个数字看起来很吓人,但他的处理方式完全出乎我意料。

二、为什么25个HIGH可以放一放

Backend镜像扫出来25个HIGH级别的CVE,全部来自基础镜像python:3.12-slim里的linux-libc-dev包。按照一般思路,看到这么多高危漏洞,要么换基础镜像,要么升级系统,要么赶紧打补丁。

但他做的是:创建一个.trivyignore文件,把这57个CVE(Backend 25个 + Frontend/Router的历史遗留32个)全部加进去。

我第一反应是:这不是掩耳盗铃吗?

他给我看了他的判断依据。每个CVE旁边都标注了EPSS分数------这是一个预测漏洞在野外被实际利用概率的模型。CVE-2013-7445的EPSS是1.225%,这是个2013年的内核漏洞,理论上很严重,但实际上从来没见过有人用它攻击。CVE-2019-19814的EPSS是1.054%,这是个F2FS文件系统的漏洞,但我们的应用根本不涉及F2FS。CVE-2021-3864的EPSS是0.336%,需要配合SUID二进制文件才能利用,我们的容器里没有这种东西。

剩下54个CVE的EPSS分数全部低于0.1%,有些甚至是0.018%。换句话说,这些漏洞被黑客用来攻击的概率,比你买彩票中奖的概率还低

他设定的阈值是1.5%。低于这个数字,并且不在应用的攻击面上(比如内核驱动、文件系统、需要物理访问的漏洞),就可以暂时忽略。但不是真的不管,而是每季度重新检查这些CVE的EPSS分数有没有上升,有没有新的PoC出现,基础镜像有没有更新版本。

他说:"CVSS评分告诉你理论上能造成多大危害,EPSS评分告诉你实际上有多少人会用它来攻击你。我们要解决的是真实威胁,不是理论威胁。"

三、优先级排序:先修能直接被打的

他把剩下27个问题分成了四个等级,每个等级都有明确的时间线。

第一优先级:立即修复(当天完成)

Router容器以root用户运行,这是最典型也最危险的配置错误。

他在Dockerfile里加了4行代码:

bash 复制代码
RUN addgroup -g 1001 -S nginx && \
    adduser -S -D -H -u 1001 -h /var/cache/nginx \
    -s /sbin/nologin -G nginx nginx
USER nginx

为什么这个问题最严重?因为一旦容器被攻破,攻击者直接拿到root权限。就好比你家的防盗门虽然装了锁,但钥匙直接插在锁上。只要进了门,整个房子随便翻。而如果用普通用户跑,攻击者就算进来了,也只能在客厅转悠,进不了主卧和保险柜。

第二优先级:本周修复(3天内完成)

python-multipart的DoS漏洞,当前版本是0.0.6,存在两个CVE。CVE-2024-24762是恶意multipart请求可以导致内存耗尽,CVE-2024-53981是畸形的boundary字段可以触发拒绝服务。

修复方法很简单,升级到0.0.18:

bash 复制代码
pip install python-multipart==0.0.18
pip freeze > requirements.txt

CVSS评分虽然是HIGH,但在实际环境中被利用的概率相对较低,因为攻击者需要能够上传文件。不过既然有现成的修复版本,没理由不升级。

Next.js的三个CVE也在这个优先级。CVE-2025-55173是图片优化功能的内容注入漏洞,CVE-2025-57752是缓存键混淆问题,CVE-2025-57822最严重,中间件重定向处理不当可能导致SSRF。当前版本是15.3.0-canary.31,需要升到15.4.7。

第三优先级:本月优化(2周内完成)

Dockerfile配置改进,这些不会直接导致安全漏洞,但能减小攻击面和提升可维护性。

Backend的Dockerfile在安装依赖时没加--no-install-recommends标志,这会导致apt额外装几十MB的推荐包,很多根本用不到。加上这个标志能把镜像体积砍掉15%,启动速度快20%,更重要的是少装的软件越少,潜在的攻击面就越小。

所有Dockerfile都缺少HEALTHCHECK指令。这个不是安全问题,但生产环境里没有健康检查,编排系统(比如Kubernetes)就不知道容器是不是真的在正常工作。可能进程还在,但服务已经死锁了,结果编排系统还在往它身上扔流量。

第四优先级:季度审查(定期复查)

基础镜像的57个CVE,这部分已经通过EPSS评分判定为低风险,但每季度要重新评估。检查EPSS分数有没有突然上升,关注是否有新的PoC代码出现,评估基础镜像是否有更新版本。

他说:"今天的低风险不代表明天还是低风险。安全扫描不是一次性任务,是持续的过程。"

四:工具选择:不是最新就是最好

他用的四个工具都是开源的,都能集成进CI/CD,都有活跃的社区维护。但他选择它们的理由各不相同。

Trivy支持文件系统和容器镜像双扫描,这意味着可以在代码阶段和打包阶段做两次检查。而且它的误报率很低,扫出来的问题基本都是真实存在的,不会像某些商业工具那样动不动报一堆False Positive,让你花时间去验证。

Grype专门用来扫SBOM,速度快得惊人。他用Syft先生成整个项目的软件物料清单,里面包含72个软件包的详细信息:名称、版本、来源、依赖关系、许可证。然后用Grype扫这个清单,30秒就能找出所有已知漏洞。这比直接扫镜像快5倍,因为不需要重复解析层级结构。

Semgrep他说比CodeQL好用。CodeQL的深度分析能力确实强,但配置复杂,规则库不够灵活,集成进CI/CD需要写一堆配置。Semgrep的规则是YAML格式,可读性高,社区贡献的规则库很丰富,而且支持自定义规则。最关键的是误报率低,扫出来的问题八成都是真的。

ClamAV虽然主要用来扫病毒,但他说"建立基线"很重要。现在扫一遍确认没问题,以后如果引入了第三方供应商的代码或者二进制文件,至少有个对比标准。病毒库有870万个签名,覆盖了几乎所有已知的恶意软件。

五:CI/CD集成:扫描要自动化

他不仅做了扫描,还给出了完整的CI/CD集成方案。在GitHub Actions的workflow里加几个步骤,每次push或者提PR的时候自动跑一遍。

Trivy的命令行参数里有个--exit-code 1,意思是发现HIGH或CRITICAL级别的漏洞就返回非零退出码,CI流程就会失败,PR就合并不了。这样能在代码合并前就把问题拦住,而不是等到生产环境才发现。

Semgrep用的是--config=auto,会自动选择适合项目语言的规则集。Python项目用Python规则,JavaScript项目用JavaScript规则,不需要手工指定。--error参数的作用是发现问题就报错,同样会阻断CI流程。

针对Python依赖用pip-audit,针对Node.js依赖用npm audit --audit-level=high。这两个工具专门检查依赖库的已知漏洞,比通用扫描器更精准。

整个workflow跑下来不到2分钟,如果发现问题,开发者在本地就能看到报错信息,直接修了再提交,不用来回折腾。

六:SBOM和架构评审

他用Syft生成的SBOM不只是用来扫漏洞,还有其他价值。

这份清单记录了项目里所有的软件包:Backend有176个包,Frontend加上npm和pnpm的依赖有几百个,Router基于Alpine镜像只有72个包。每个包都标注了版本号、来源仓库、许可证类型(GPL、MIT、Apache等)、依赖关系树。

以后如果某个第三方库爆出新漏洞,比如Log4j那种级别的,可以立刻在SBOM里搜索,确认我们用没用,用的哪个版本,受不受影响。不需要去代码里一个个翻requirements.txtpackage.json,也不需要猜测间接依赖有没有引入这个库。

而且很多行业有合规要求,必须提供软件物料清单,证明你知道自己用了哪些开源组件,有没有侵犯许可证条款。SBOM就是这个证明材料。

他在扫描的过程中顺手做了代码审查,发现了几个架构级的问题。

Backend的目录结构是单层扁平的,所有Agent放在agent_group文件夹里,编排逻辑在langgraph_orchestrator里,缓存在schema_cache里,还有个重复的schema_cache.pkl文件也在根目录下。这种结构在项目小的时候还能凑合,但现在已经有几十个文件了,再往后加新功能会越来越乱。

他建议做分层设计:核心编排逻辑单独一层,各种Agent做成插件架构,存储层(缓存和持久化)单独一层,API层单独一层,配置管理单独一层。这样以后加新的Agent不需要改主代码,只需要写个插件注册进去就行。

更严重的是,整个Backend目录下没有一个测试文件。他的原话是:"没有测试的代码就是遗留代码。你不知道它能不能工作,也不敢改它,因为改了不知道会不会炸。"

当前代码是单线程设计,但他说即使现在只支持单用户,架构也要为未来的多用户场景预留接口。会话隔离、状态管理、并发控制,这些现在不做,以后重构的成本会高十倍。


业余做法是扫一次就完事,报告放在那儿半年没人看。专业做法是建立持续监控机制,集成进CI/CD自动化运行,设置季度复查时间表,确保系统能够持续运行。

业余做法是发现问题就堆在那儿,不知道先修哪个。专业做法是按照攻击面、利用难度、修复成本、业务影响做优先级排序,给每个等级设置明确的时间线和责任人。

不是临时抱佛脚,不是应付检查,而是把安全融入到日常开发流程里,让每一次提交都经过自动化的安全检查,让每一个决策都有数据和逻辑支撑。


可以直接抄的配置

如果你想在自己的项目里做同样的事情,这里是完整的工具安装和配置。

安装工具(macOS,其他系统把brew换成对应的包管理器):

bash 复制代码
brew install trivy grype syft semgrep clamav

Trivy扫描

bash 复制代码
# 扫描文件系统
trivy fs --scanners vuln,secret,misconfig ./

# 扫描容器镜像
trivy image --severity HIGH,CRITICAL your-image:tag

# 生成忽略列表
echo "CVE-2013-7445" >> .trivyignore

生成SBOM并扫描

bash 复制代码
syft your-image:tag -o cyclonedx-json > sbom.json
grype sbom:sbom.json

GitHub Actions配置(.github/workflows/security.yml):

bash 复制代码
name: Security Scan
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Trivy FS Scan
        run: trivy fs --exit-code 1 --severity HIGH,CRITICAL .
      - name: Semgrep
        run: semgrep scan --config=auto --error

Dockerfile最佳实践

bash 复制代码
# 使用非root用户
RUN adduser -S -D -H -u 1001 appuser
USER appuser

# 减小镜像体积
RUN apt-get update && apt-get install -y --no-install-recommends \
    package1 package2 \
    && rm -rf /var/lib/apt/lists/*

# 添加健康检查
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8080/health || exit 1

EPSS分数查询 :去 www.first.org/epss/ 输入CVE编号就能看到最新的利用预测分数。

最后

这位佬做的事情其实不复杂,就是标准的DevSecOps流程:扫描、评估、分级、修复、持续监控。但大部分团队停在扫描环节,扫完就放那儿。少数团队做了修复,但没建立持续监控。更少团队会用EPSS做风险评估,而不是盲目修所有HIGH。

相关推荐
skilllite作者16 分钟前
AI 自进化系统架构详解 (一):重新定义 L1-L3 等级,揭秘 OpenClaw 背后的安全边界
人工智能·安全·系统架构
夏冰加密软件35 分钟前
【实测】文件加密软件解除保护的2种方法(以超级加密3000为例)
windows·安全
a1117761 小时前
网络安全检查表 docx 附文件
网络·安全·web安全
上海云盾商务经理杨杨2 小时前
DDoS攻击日志分析与攻击源定位实战
安全·ddos
dashizhi20155 小时前
电脑禁用U口、禁用USB端口、屏蔽移动存储设备使用的方法
windows·安全·电脑
洒满阳光的午后5 小时前
一个基于Runbook的版本发布系统设计思路
devops·cicd
东北甜妹6 小时前
Redis 知识总结
运维·nginx·安全
夫子樊6 小时前
资损防控与安全生产
安全
星幻元宇VR6 小时前
VR星际行走平台|沉浸式科普教育与未来体验的新入口
科技·学习·安全·生活·vr
feixiangyuncai6 小时前
数字生态系统赋能供水安全与可持续发展
安全·智慧城市