SpringBoot Data JPA Repository 能否安全防范 SQL 注入?

Rav*_*r B 3 java spring spring-data-jpa spring-boot checkmarx

我有一个 Springboot 应用程序,它使用 Spring Data JPA 模块进行数据库操作。当我们扫描代码时,checkmarx 报告了许多有关 SQL_Injection 攻击的高和中评级问题。以下是用例之一,我需要帮助来确定是否将问题标记为误报。如果不是误报,我应该做什么来解决这个问题?

应用程序控制器.Java

@Controller
public class AppController
{
    private static final Logger logger = LoggerFactory.getLogger(AppController.class);

    @Autowired
    private AppService appService;
    
    @RequestMapping(value = "/propertiesHistory", method = RequestMethod.POST)
    public String getPropertiesHistory(@ModelAttribute("propSearchForm") @Validated PropertiesSearch propertiesSearch, BindingResult result, Model model, final RedirectAttributes redirectAttributes)
    {
        String instanceName = propertiesSearch.getInstanceName();
        
        if (!propertiesSearch.getInstanceName().equalsIgnoreCase("NONE"))
        {
            List<String> propVersionDates = appService.getPropertyHistoryDates(instanceName);
            //Some Businees Logic
        }

        if (result.hasErrors())
        {
            logger.warn("getPropertiesHistory() : Binding error - " + result.getAllErrors());
        }
        else
        {
            //Some Businees Logic
        }
        return "app/prophist";
    }
}
Run Code Online (Sandbox Code Playgroud)

应用服务.java

@Service
public class AppService
{
    private static final Logger logger = LoggerFactory.getLogger(AppService.class);
    
    @Autowired
    private AppRepository appRepository;
    
    public List<String> getPropertyHistoryDates(String instanceName)
    {
        List<String> list = new ArrayList<String>();
        try
        {
            list = appRepository.findAllMDateDESCByProNotEmptyAndInstanceName(instanceName);
        }
        catch (Exception e)
        {
            logger.error("getPropertyHistoryDates(): Error while fetching data from database - ", e);
        }
        
        return list;
    }
}
Run Code Online (Sandbox Code Playgroud)

应用程序存储库.java

public interface AppRepository extends JpaRepository<AppDataEntity, Long>
{
    @Query(value="SELECT mdate FROM tablexyz WHERE properties IS NOT NULL AND instanceName =:instanceName ORDER BY mdate DESC",nativeQuery=true)
    List<String> findAllMDateDESCByProNotEmptyAndInstanceName(@Param("instanceName") String instanceName);
}
Run Code Online (Sandbox Code Playgroud)

我还有一些方法,例如List<AppDataEntity> findAllByInstanceName(String instanceName);存储库中的方法,它使用代理类实现,但不使用本机查询。在这种情况下,我也会遇到这个Checkmarx 问题 - SQL_Injection

我读到Spring Data 不会改变 Hibernate根据此处接受的答案处理实体的方式。这是真的并且适用于@Query(value="some query",nativeQuery=true).?

Rav*_*r B 8

只要我们在 @Query(JPQL) 或 @Query(nativeQuery) 中具有命名或索引/位置参数,SpringBoot Data JPA Repository 就可以安全地抵御 SQL_Injection 攻击。

是的,对于下面的问题。它适用于 @Query() 的唯一条件是查询应该具有命名 (:paramname) 或位置 (?1) 参数。

我读到Spring Data 不会改变 Hibernate 根据此处接受的答案处理实体的方式。这是真的并且适用于 @Query(value="some query",nativeQuery=true) 吗?

以下是针对 sql 注入的安全措施。

@Query(value="SELECT mdate FROM tablexyz WHERE properties IS NOT NULL AND instanceName =:instanceName ORDER BY mdate DESC",nativeQuery=true)
    List<String> findAllMDateDESCByProNotEmptyAndInstanceName(@Param("instanceName") String instanceName);
Run Code Online (Sandbox Code Playgroud)

原因很简单,Spring Data JPA 在后台使用 hibernate,而 hibernate 又使用PreparedStatements 方式来处理数据库。

关于PreparedStatements方式如何保护我们的应用程序免受SQL_Injection攻击的非常详细的解释可以在这里这里找到