You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Checkmarx标记含@Query的JPA非参数化查询方法为存储型XSS风险,如何解决?

问题分析与解决建议

这是Checkmarx的误报

你的JPA仓库方法不存在存储型XSS风险:

  • 该自定义查询是完全静态的,没有引入任何用户可控的输入参数,不存在SQL注入或恶意内容注入的可能;
  • 存储型XSS的风险核心是恶意内容写入数据库后,前端未转义直接渲染,而你的服务层已经通过StringEscapeUtils::escapeHtml4对返回值做了转义,后续渲染的风险已被覆盖;
  • Checkmarx的扫描规则大概率只是简单匹配@Query注解就触发告警,没有区分查询是否包含用户输入。

解决方式

1. 标记为误报

在Checkmarx平台找到对应告警,将其标记为误报,并补充说明:

该自定义查询无用户输入参数,仅做数据库字段拼接,返回值已在服务层完成HTML转义,不存在XSS风险。

2. 替换自定义@Query为Criteria API

如果想彻底绕过扫描规则,可用JPA Criteria API实现相同逻辑,避免使用@Query注解:

import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface PersonRepository extends JpaRepository<PersonEntity, Long>, JpaSpecificationExecutor<PersonEntity> {

    default String[] findDistinctNames() {
        Specification<PersonEntity> spec = (Root<PersonEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            // 拼接firstName和lastName
            var fullName = cb.concat(cb.concat(root.get("firstName"), cb.literal(" ")), root.get("lastName"));
            // 构建去重查询
            query.select(fullName).distinct(true);
            return null;
        };
        // 转换结果为字符串数组
        return findAll(spec).stream()
                .map(Object::toString)
                .toArray(String[]::new);
    }
}

3. 添加代码注释

在仓库方法上添加明确注释,帮助扫描工具或审核人员快速识别风险情况:

/**
 * 查询去重的人员全名,无用户输入参数,返回值已在服务层通过StringEscapeUtils::escapeHtml4做HTML转义
 * 无存储型XSS风险
 */
@Query("select distinct concat(p.firstName, ' ', p.lastName) as name from PersonEntity p")
public String[] findDistinctNames();

4. 调整扫描规则(若有权限)

如果团队有权限修改Checkmarx的扫描规则,可以针对无参数的@Query方法调整检测逻辑,只对包含用户输入参数的自定义查询触发XSS告警。


内容的提问来源于stack exchange,提问作者Knight Steele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:57:20