sql的表名和字段都是不确定的 所以只能执行sql
<insert id="insertSql" parameterType="String">
${sql}
</insert>
像这种 有没有办法检测这个拼接好的sql字符串有问题
sql的表名和字段都是不确定的 所以只能执行sql
<insert id="insertSql" parameterType="String">
${sql}
</insert>
像这种 有没有办法检测这个拼接好的sql字符串有问题
我觉得要直接在mapper文件里(用了$)处理sql注入问题是不可能的
mybatis已经明确指出, 使用#能够防止sql注入, $则不能, 一定要用也没办法呀
那么既然使用 $ 就应该要确保穿进去的sql是安全的对吧?
我的建议只能是在sql进入mapper之前就做好预防
推荐2, 更加简单, 直接
就算表名和字段都是不确定的,查询和更新还是要区分区分吧?
改成 select ${columns} from ${table} where ${condition} 这种,然后columns、table、condition这些进行校验,只能是一些固定内容,不知道能不能行。
另外这个功能使用的数据库用户也可以和其他功能区分开,使用mybatis-plus的dynamic-datasource可以配置多个数据源,这个服务使用一个只查询某个表的权限的用户,这样也可以稍微限制一下。
对于不确定是不可能的,你可以在information_schema查询所有表名和字段。
当然你使用mybatis肯定是有实体类的,针对实体类进行aop拦截只允许实体类的字段和表名即可;
@Aspect
@Component
@Slf4j
@ConditionalOnProperty(value = "sql.statement.filter", havingValue = "true")
public class StatementAop {
@Pointcut("@within(com.yumc.store.cpos.ikitchen.common.annotation.StatmentMethod) || @annotation(com.yumc.store.cpos.ikitchen.common.annotation.StatmentMethod) ")
public void mapping() {
}
.......
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.PARAMETER})
public @interface StatementColumn {
//自定义错误
String msg() default "错误的排序字段";
}
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.TYPE, ElementType.METHOD,ElementType.PARAMETER})
public @interface StatmentMethod {
String[] columns() default {};
}
@StatmentMethod
List<ArrivalTimeConfig> selectPageInfo(ArrivalTimeConfigInput configInput);
@StatmentMethod
List<WaitingTimeConfig> selectPageInfo(@StatementColumn WaitingTimeConfigInput info);
以上代码简单演示,
使用拦截方法来验证外部传入的是否符合既定的实体所拥有的字段和对应的表名,
然后你就可以安全的使用外部的数据,
对于一层解决不了的问题 增加一层即可。
15 回答8.4k 阅读
8 回答6.2k 阅读
5 回答3.2k 阅读✓ 已解决
3 回答3.6k 阅读✓ 已解决
1 回答4k 阅读✓ 已解决
3 回答6k 阅读
2 回答2.8k 阅读✓ 已解决
既然用mybatis了。 为啥还直接传进来整个sql。