普元EOS中namingsql(命名sql)动态传入表名造成的SQL注入的解决方案

时间:2022-08-12 21:39:21
转至元数据起始

如何解决动态数据表名,动态字段名情况下,由缓存select字段而引起的映射字段找不到的情况?

以下是解决办法!

先看一个常规查询示例:

1、准备两个数据库,数据库表结构如下:

普元EOS中namingsql(命名sql)动态传入表名造成的SQL注入的解决方案

2、命名sql的编写:queryBasedbData.namingsqlx

?
<? xml version = "1.0" encoding = "UTF-8" ?>
<!-- author:lianzh -->
< sqlMap  namespace = "Account" >
     < parameterMap class = "commonj.sdo.DataObject" id = "parameterMap" >
         < parameter javaType = "date" jdbcType = "DATE" property = "dateType" />
     </ parameterMap >
     < resultMap class = "commonj.sdo.DataObject" id = "resultMap" >
         < result column = "TYPEID" javaType = "string" property = "typeId" />
     </ resultMap >
     < select id = "select_data_test" parameterClass = "java.util.HashMap" resultClass = "commonj.sdo.DataObject" >
          select * from $tablename$
     </ select >
</ sqlMap >

其中$tablename$ 表名是可以动态修改的。

3、创建逻辑流,调用queryByNamedSql,根据命名sql查询数据库,具体如下:

普元EOS中namingsql(命名sql)动态传入表名造成的SQL注入的解决方案

普元EOS中namingsql(命名sql)动态传入表名造成的SQL注入的解决方案

普元EOS中namingsql(命名sql)动态传入表名造成的SQL注入的解决方案

 

4、调用逻辑流,查询结果如下,可正常查询:

<DataObject __type="sdo:commonj.sdo.DataObject" __id="0">

                      <id1 __type="java:java.lang.String">11</id1>

                     <name1 __type="java:java.lang.String">name11</name1>

</DataObject>

5、将赋值中的表名修改为a_user2

普元EOS中namingsql(命名sql)动态传入表名造成的SQL注入的解决方案

6、运行逻辑流,跟踪代码

自动加载映射是false

普元EOS中namingsql(命名sql)动态传入表名造成的SQL注入的解决方案

所以由于缓存机制,映射的还是之前表的字段id1 而不是id2:

普元EOS中namingsql(命名sql)动态传入表名造成的SQL注入的解决方案

虽然根据命名sql中的sql语句可以查询表的结果,但是却无法进行映射,报如下“字段找不到”异常:

普元EOS中namingsql(命名sql)动态传入表名造成的SQL注入的解决方案

7、解决方案

EOS的帮助文档中对命名sql各元素的属性有描述,但是描述不全,没有对重新加载命名sql的属性进行描述。

参考ibatis,需要在动态传入表名时,重新进行映射,设置 remapResults="true"。

如上例:需要在<select></select>标签中,加入remapResults="true",如下:

?
< select id = "select_data_test" parameterClass = "java.util.HashMap" resultClass = "commonj.sdo.DataObject" remapResults = "true" >
         select * from $tablename$
</ select >

8、只有在动态加载表名时增加该属性,其他情况下不需要,否则性能有影响。