springboot动态查询表名修改,他们提的sql注入没看懂

动态表名查询

img

img


controller
 @RequestMapping(value = "/chaXun1")
    @ResponseBody
    @CrossOrigin
    public List<Map<String,Object>> test(@RequestBody String tableName){
        List<Map<String, Object>> fishLogs = userService.getFishLogs(tableName);
        return fishLogs;
    }


mapper

public List<Map<String,Object>> getFishLogs(@Param("tableName") String tableName);



impl
  @Override
    public List<Map<String, Object>> getFishLogs(String tableName) {
        return easyExeclMapper.getFishLogs(tableName);
    }


xml
<select id="getFishLogs" resultType="java.util.Map" statementType="STATEMENT">
        select * from ${tableName}
    </select>

打印一下 这个 tableName,看看是不是 一个 json串

img

尝试 改下:

public List<Map<String,Object>> test(@RequestBody String tableName)

// 修改 
public List<Map<String,Object>> test(@RequestParam("tableName") String tableName)
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/372872
  • 你也可以参考下这篇文章:springboot启动运行.sql文件自动建表
  • 除此之外, 这篇博客: SpringBoot启动执行sql脚本的三种方式中的 背景 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 项目里后端需要计算坐标距离,想用sql实现算法,然后通过执行一个sql脚本,创建一个函数供各业务调用。我们需要在springboot项目启动时执行sql脚本,在网上一顿搜索,总结了有三种做法:

    • 配置application.yml文件
    • 自定义DataSourceInitializer Bean
    • 启动时执行方法

    第一种做法最方便简洁,是首选方案,但是由于种种原因项目里不能用,只能选择使用第二种做法。第三种做法不推荐,这里只当是记录一下做过的工作。

    开发调测sql脚本的时候,推荐使用这个驱动,可以让我们看到sql执行日志,有没有执行?报了什么异常?

    spring
      datasource
        driver-class-name: net.sf.log4jdbc.DriverSpy
    
    <dependency>
    	<groupId>com.googlecode.log4jdbc</groupId>
    	<artifactId>log4jdbc</artifactId>
    	<version>1.2</version>
    	<scope>runtime</scope>
    </dependency>
    

    同时,spring.datasource.url的配置应该如下起头

    spring
      datasource
        url: 'jdbc:log4jdbc:mysql://XXXXX'
    


源于chatGPT仅供参考


根据您提供的代码,我理解到你的问题是关于动态表名查询时可能存在的SQL注入问题。在这种情况下,通过从用户输入中获取表名并直接拼接到SQL语句中,可能导致潜在的安全风险。

例如,在你的XML映射文件中,你使用`${tableName}`将用户提供的表名直接插入到SQL语句中。这种做法可能会导致SQL注入攻击,即使在此处看起来可能没有明显的问题。如果恶意用户提供恶意的输入,他们可能会尝试执行恶意的SQL语句或破坏数据。

要解决这个问题,可以使用MyBatis的参数化查询(Prepared Statement)来动态设置表名,而不是直接将用户输入插入到SQL语句中。修改如下:

XML映射文件:
```xml
<select id="getFishLogs" resultType="java.util.Map" statementType="STATEMENT">
    select * from #{tableName}
</select>

userServiceImpl中:

@Override
public List<Map<String, Object>> getFishLogs(String tableName) {
    Map<String, Object> parameterMap = new HashMap<>();
    parameterMap.put("tableName", tableName);
    return easyExeclMapper.getFishLogs(parameterMap);
}

在mapper中:

public List<Map<String,Object>> getFishLogs(Map<String, Object> parameterMap);

这样,使用#{tableName}而不是${tableName}可以将表名作为参数传递给SQL语句,提供更安全的查询方式。 MyBatis将负责确保用户输入值被正确地转义和处理,从而避免潜在的SQL注入攻击。

请务必注意输入验证和安全性问题,并在接受用户输入时采取适当的防护措施,以确保应用程序的安全性和健壮性。

```