Spring Data REST代码审计浅析
字数 1652 2025-08-18 11:35:40

Spring Data REST 代码审计指南

0. 概述

Spring Data REST 是建立在 Data Repository 之上的框架,能够直接将 repository 以 HATEOAS 风格暴露为 Web 服务,无需手动编写 Controller 层。本指南将深入分析 Spring Data REST 的工作原理和安全风险。

1. 请求路径组成

1.1 基础路径配置

默认根路径为 /,可通过以下方式修改:

  1. 配置文件方式:
spring.data.rest.basePath=/api
  1. 编程方式(高版本):
@Configuration
class CustomRestMvcConfiguration {
    @Bean
    public RepositoryRestConfigurer repositoryRestConfigurer() {
        return new RepositoryRestConfigurer() {
            @Override
            public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
                config.setBasePath("/api");
            }
        };
    }
}

1.2 路径类型

示例 Repository:

@RepositoryRestResource(path = "tenantPath")
public interface TenantRepository extends CrudRepository<Tenant, Long> {
    Page<Tenant> findAllByNameContaining(String name, Pageable page);
    Page<Tenant> findAllByIdCardContaining(String idCard, Pageable page);
    
    @RestResource(path = "mobile", rel = "mobile")
    Tenant findFirstByMobile(String mobile);
    
    @RestResource(exported = false)
    Tenant findFirstByIdCard(String idCard);
}

路径类型包括:

  • 仓库路径(Repository Path):如 /tenants/tenantPath
  • 实体资源路径(Entity Resource Path):如 /tenants/1
  • 查询路径(Search Path):如 /tenants/search/findAllByNameContaining
  • 关系路径(Association Path):如 /tenants/1/address
  • Profile 路径/profile 提供服务器元信息

2. 请求解析过程

2.1 处理流程

  1. 请求由 DispatcherServlet 处理

  2. 使用 DelegatingHandlerMapping 委托给:

    • RepositoryRestHandlerMapping
    • BasePathAwareHandlerMapping
  3. 主要处理以下注解的类:

@RepositoryRestController // 处理仓库相关请求
@BasePathAwareController // 处理基础路径相关请求

2.2 详细解析示例

/tenantPath/search/findAllByIdCardContaining 请求为例:

  1. RepositoryRestHandlerMapping#getHandlerInternal 获取 handler
  2. 初始化请求路径(考虑 PathPattern 解析器)
  3. 从请求头获取 Accept 值并处理
  4. 匹配 RequestMappingInfo 对象
  5. 获取 repositoryLookupPath(处理 baseUri)
  6. 获取 RepositoryBasePath
  7. 检查路径是否匹配 metadata
  8. 创建 PathPattern 并设置到请求属性
  9. 最终映射到 RepositorySearchController#executeSearch

2.3 与 Spring Web 的区别

  1. 不使用 RequestMappingHandlerMapping,而是使用专门的 REST 处理器映射
  2. 路径处理:
    • 支持尾部额外 /(会被剔除)
    • 不支持 URL 编码路径(如 /%7Brepository%7D/search/%7Bsearch%7D 会返回 404)

3. 安全风险与防护

3.1 ALPS 文档信息泄露

风险

  • 默认暴露 ALPS 文档(/profile
  • 包含资源、属性、关系和操作等元信息

防护措施

@Configuration
public class CustomRestMvcConfiguration {
    @Bean
    public RepositoryRestConfigurer repositoryRestConfigurer() {
        return new RepositoryRestConfigurer() {
            @Override
            public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
                config.getMetadataConfiguration().setAlpsEnabled(false);
            }
        };
    }
}

3.2 端点暴露控制

防护方法

  1. 接口级别禁用:
@RepositoryRestResource(exported = false)
public interface SensitiveRepository extends CrudRepository<Sensitive, Long> {}
  1. 方法级别禁用:
@RestResource(exported = false)
Tenant findFirstByIdCard(String idCard);
  1. 安全配置建议:
  • 使用 MvcRequestMatcher 而非 AntPathRequestMatcher
  • 获取完整路径的方式:
PathPattern pathPattern = (PathPattern) request.getAttribute(
    "org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.EFFECTIVE_REPOSITORY_RESOURCE_LOOKUP_PATH");
String requestPath = pathPattern.getPatternString();

3.3 敏感数据暴露

防护措施

  1. 使用投影(Projections)控制返回字段
  2. 避免暴露实体所有字段

3.4 拒绝服务(DoS)

防护措施

  1. 限制查询返回结果数量
  2. 配置合适的分页和排序

3.5 其他风险

  1. SQL 注入:需审计 Repository 方法
  2. 权限控制:确保适当鉴权

4. 最佳实践

  1. 禁用不必要的 ALPS 文档
  2. 严格控制暴露的端点
  3. 使用投影保护敏感数据
  4. 实现适当的分页限制
  5. 使用 MvcRequestMatcher 进行路径匹配
  6. 定期审计 Repository 方法安全性

通过遵循这些指南,可以显著提高 Spring Data REST 应用的安全性,减少潜在的安全风险。

Spring Data REST 代码审计指南 0. 概述 Spring Data REST 是建立在 Data Repository 之上的框架,能够直接将 repository 以 HATEOAS 风格暴露为 Web 服务,无需手动编写 Controller 层。本指南将深入分析 Spring Data REST 的工作原理和安全风险。 1. 请求路径组成 1.1 基础路径配置 默认根路径为 / ,可通过以下方式修改: 配置文件方式: 编程方式(高版本): 1.2 路径类型 示例 Repository: 路径类型包括: 仓库路径(Repository Path) :如 /tenants 或 /tenantPath 实体资源路径(Entity Resource Path) :如 /tenants/1 查询路径(Search Path) :如 /tenants/search/findAllByNameContaining 关系路径(Association Path) :如 /tenants/1/address Profile 路径 : /profile 提供服务器元信息 2. 请求解析过程 2.1 处理流程 请求由 DispatcherServlet 处理 使用 DelegatingHandlerMapping 委托给: RepositoryRestHandlerMapping BasePathAwareHandlerMapping 主要处理以下注解的类: 2.2 详细解析示例 以 /tenantPath/search/findAllByIdCardContaining 请求为例: RepositoryRestHandlerMapping#getHandlerInternal 获取 handler 初始化请求路径(考虑 PathPattern 解析器) 从请求头获取 Accept 值并处理 匹配 RequestMappingInfo 对象 获取 repositoryLookupPath (处理 baseUri) 获取 RepositoryBasePath 检查路径是否匹配 metadata 创建 PathPattern 并设置到请求属性 最终映射到 RepositorySearchController#executeSearch 2.3 与 Spring Web 的区别 不使用 RequestMappingHandlerMapping ,而是使用专门的 REST 处理器映射 路径处理: 支持尾部额外 / (会被剔除) 不支持 URL 编码路径(如 /%7Brepository%7D/search/%7Bsearch%7D 会返回 404) 3. 安全风险与防护 3.1 ALPS 文档信息泄露 风险 : 默认暴露 ALPS 文档( /profile ) 包含资源、属性、关系和操作等元信息 防护措施 : 3.2 端点暴露控制 防护方法 : 接口级别禁用: 方法级别禁用: 安全配置建议: 使用 MvcRequestMatcher 而非 AntPathRequestMatcher 获取完整路径的方式: 3.3 敏感数据暴露 防护措施 : 使用投影(Projections)控制返回字段 避免暴露实体所有字段 3.4 拒绝服务(DoS) 防护措施 : 限制查询返回结果数量 配置合适的分页和排序 3.5 其他风险 SQL 注入:需审计 Repository 方法 权限控制:确保适当鉴权 4. 最佳实践 禁用不必要的 ALPS 文档 严格控制暴露的端点 使用投影保护敏感数据 实现适当的分页限制 使用 MvcRequestMatcher 进行路径匹配 定期审计 Repository 方法安全性 通过遵循这些指南,可以显著提高 Spring Data REST 应用的安全性,减少潜在的安全风险。