三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

从一次内部攻防演练看Solr CVE-2019-17558:攻击链分析与Java安全编码启示

从一次内部攻防演练看Solr CVE-2019-17558:攻击链分析与Java安全编码启示

企业级Solr安全攻防实战:从CVE-2019-17558漏洞链到Java安全编码范式

当安全团队在年度红蓝对抗演练中遭遇Solr服务时,攻击者往往会在看似无害的搜索接口前露出微笑。这个基于Java构建的高性能搜索平台,曾因Velocity模板注入漏洞(CVE-2019-17558)让众多企业付出惨痛代价。本文将还原攻击者视角下的完整入侵链条,并逆向推导出Java Web应用的安全开发范式。

1. 漏洞全景:当搜索框变成攻击入口

2019年曝光的这个高危漏洞,本质是Solr对Velocity模板引擎的配置缺陷。攻击者通过精心构造的HTTP请求,可以绕过默认配置限制,在服务端执行任意系统命令。我们先看一个典型的攻击路径:

  1. 侦察阶段:攻击者扫描发现开放8983端口的Solr服务
  2. 核心探测:通过/solr/admin/cores?indexInfo=false&wt=json接口获取核心名称
  3. 配置篡改:修改params.resource.loader.enabled为true启用危险功能
  4. 载荷投递:注入Velocity模板实现RCE(远程代码执行)

关键攻击载荷示例:

GET /solr/demo/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))...

漏洞影响矩阵

维度影响范围风险等级
版本Solr 5.0.0 - 8.3.1严重
默认配置params.resource.loader.enabled=false中危
攻击复杂度需先修改配置高危

2. 深度拆解:Velocity模板注入的技术本质

Velocity模板引擎本应安全地渲染页面,但当它遇到以下组合时就会变成危险武器:

  • 沙箱逃逸:通过Java反射机制获取Runtime类
  • 字符拼接:利用URL编码绕过基础过滤
  • 链式调用:构建完整的命令执行链条

典型攻击代码结构:

#set($x='') #set($rt=$x.class.forName('java.lang.Runtime')) #set($chr=$x.class.forName('java.lang.Character')) #set($ex=$rt.getRuntime().exec('whoami'))

防御者需要特别警惕以下危险模式:

  • 动态类加载(Class.forName)
  • 反射调用(getMethod/invoke)
  • 进程执行(Runtime.exec)

3. 企业级防御:从漏洞修复到架构免疫

3.1 紧急处置方案

对于受影响的Solr实例,建议立即实施:

  1. 版本升级:升级到Solr 8.3.1以上版本
  2. 配置加固
    params.resource.loader.enabled=false solr.resource.loader.enabled=false
  3. 网络隔离:限制8983端口的访问来源

3.2 Java安全编码黄金法则

基于该漏洞的教训,我们提炼出Java Web应用的安全准则:

输入验证规范

  • 实施白名单校验(正则表达式示例):
    private static final Pattern SAFE_TEMPLATE_PATTERN = Pattern.compile("^[a-zA-Z0-9_\\-\\s]+$");
  • 禁用高风险字符:
    String sanitized = input.replaceAll("[#${}]", "");

安全配置清单

  1. 模板引擎沙箱模式必须开启
  2. 反射调用需进行签名验证
  3. 禁止动态加载不受信任的类

4. 攻防演进:现代WAF的检测逻辑对抗

新一代Web应用防火墙针对此类攻击通常采用多层检测:

  1. 语法特征检测

    • Velocity指令特征(#set、#foreach)
    • Java反射关键字(Class.forName、getRuntime)
  2. 行为模式识别

    • 短时间内配置修改+模板注入请求
    • 异常的命令执行结果获取
  3. 流量基线对比

    • 正常Solr API调用模式
    • 异常参数组合报警

企业可参考以下检测规则示例:

rules: - id: solr_velocity_injection pattern: | (?i)(\\$\\{.*\\}| #set\\(\\$[a-z]+=| \\.forName\\(| getRuntime\\(\\)) severity: CRITICAL

5. 安全开发生命周期实践

将安全嵌入开发全流程:

设计阶段

  • 最小化模板引擎功能集
  • 定义清晰的输入输出契约

实现阶段

// 安全的Velocity初始化示例 public class SafeVelocityEngine extends VelocityEngine { @Override public void init() { super.setProperty(RuntimeConstants.RUNTIME_REFERENCES_STRICT, true); super.setProperty(RuntimeConstants.CUSTOM_DIRECTIVES, Collections.emptyList()); } }

测试阶段

  • DAST扫描:模拟模板注入攻击
  • IAST监控:运行时检测危险调用

在最近某金融企业的攻防演练中,正是通过静态代码分析发现了类似的模板引擎误用模式,避免了潜在的数百万损失。安全团队建立的Java EE组件安全使用规范,已成为该企业新员工培训的必修内容。

← 返回列表