我有一个接受用户输入的SQL查询,因此存在安全漏洞。
现有查询为:
SELECT BUS_NM, STR_ADDR_1, CITY_NM, STATE_CD, POSTAL_CD, COUNTRY_CD,
BUS_PHONE_NB,PEG_ACCOUNT_ID, GDN_ALERT_ID, GBIN, GDN_MON_REF_NB,
ALERT_DT, ALERT_TYPE, ALERT_DESC,ALERT_PRIORITY
FROM ( SELECT A.BUS_NM, AE.STR_ADDR_1, A.CITY_NM, A.STATE_CD, A.POSTAL_CD,
CC.COUNTRY_CD, A.BUS_PHONE_NB, A.PEG_ACCOUNT_ID, 'I' ||
LPAD(INTL_ALERT_DTL_ID, 9,'0') GDN_ALERT_ID,
LPAD(IA.GBIN, 9,'0') GBIN, IA.GDN_MON_REF_NB,
DATE(IAD.ALERT_TS) ALERT_DT,
XMLCAST(XMLQUERY('$A/alertTypeConfig/biqCode/text()' passing
IAC.INTL_ALERT_TYPE_CONFIG as "A") AS CHAR(4)) ALERT_TYPE,
, ROW_NUMBER() OVER () AS "RN"
FROM ACCOUNT A, Other tables
WHERE IA.GDN_MON_REF_NB = '100'
AND A.PEG_ACCOUNT_ID = IAAR.PEG_ACCOUNT_ID
AND CC.COUNTRY_CD = A.COUNTRY_ISO3_CD
ORDER BY IA.INTL_ALERT_ID ASC )
WHERE ALERT_TYPE IN (" +TriggerType+ ");
我将其更改为从setString接受TriggerType,例如:
SELECT BUS_NM, STR_ADDR_1, CITY_NM, STATE_CD, POSTAL_CD, COUNTRY_CD,
BUS_PHONE_NB,PEG_ACCOUNT_ID, GDN_ALERT_ID, GBIN, GDN_MON_REF_NB,
ALERT_DT, ALERT_TYPE, ALERT_DESC,ALERT_PRIORITY
FROM ( SELECT A.BUS_NM, AE.STR_ADDR_1, A.CITY_NM, A.STATE_CD, A.POSTAL_CD,
CC.COUNTRY_CD, A.BUS_PHONE_NB, A.PEG_ACCOUNT_ID,
'I' || LPAD(INTL_ALERT_DTL_ID, 9,'0') GDN_ALERT_ID,
LPAD(IA.GBIN, 9,'0') GBIN, IA.GDN_MON_REF_NB,
DATE(IAD.ALERT_TS) ALERT_DT,
XMLCAST(XMLQUERY('$A/alertTypeConfig/biqCode/text()' passing
IAC.INTL_ALERT_TYPE_CONFIG as "A") AS CHAR(4)) ALERT_TYPE,
ROW_NUMBER() OVER () AS "RN"
FROM ACCOUNT A, other tables
WHERE IA.GDN_MON_REF_NB = '100'
AND A.PEG_ACCOUNT_ID = IAAR.PEG_ACCOUNT_ID
AND CC.COUNTRY_CD = A.COUNTRY_ISO3_CD
ORDER BY IA.INTL_ALERT_ID ASC )
WHERE ALERT_TYPE IN (?);
设置触发类型如下:
if (StringUtils.isNotBlank(request.getTriggerType())) {
preparedStatement.setString(1, triggerType != null ? triggerType.toString() : "");
}
获取错误
由以下原因引起:com.ibm.db2.jcc.am.SqlDataException:DB2 SQL错误:SQLCODE = -302,SQLSTATE = 22001,SQLERRMC = null,DRIVER = 4.19.26
答案 0 :(得分:0)
-302 SQLCODE表示某种转换错误。
SQLSTATE 22001通过告诉我们您正在尝试将大字符串强制为小变量来缩小范围。鉴于您的问题信息有限,我猜想是XMLCAST
才是罪魁祸首。
DB2不会将30磅的废纸jam塞到4磅的袋子中,可以这么说,这会给您带来错误。也许在转换中给XML一些额外的空间可能会有所帮助。如果需要确保它最终只有4个字符长,则可以显式执行LEFT(XMLCAST( ... AS VARCHAR(64)), 4)
。这样,XMLCAST
便拥有了所需的空间,但是您将其切回以适合您的变量,以适应提取。
另一件事可能是传递给参数标记的变量太长。 DB2将根据ALERT_TYPE
的长度猜测类型和长度。请注意,您只能通过参数标记传递单个值。如果传递逗号分隔的列表,它将不会按预期方式工作(除非您期望ALERT_TYPE
也包含逗号分隔的列表)。如果要从表中获取逗号分隔的列表,则可以使用子选择。
答案 1 :(得分:0)
IN ('AAAA, M250, ABCD')
谓词与参数一起使用错误。
不要指望IN ('AAAA', 'M250', 'ABCD')
(在您尝试通过逗号分隔的字符串作为单个参数传递时)会像select t.*
from
(
select XMLCAST(XMLQUERY('$A/alertTypeConfig/biqCode/text()' passing IAC.INTL_ALERT_TYPE_CONFIG as "A") AS CHAR(4)) ALERT_TYPE
from table(values xmlparse(document '<alertTypeConfig><biqCode>M250, really big code</biqCode></alertTypeConfig>')) IAC(INTL_ALERT_TYPE_CONFIG)
) t
--WHERE ALERT_TYPE IN ('AAAA, M250, ABCD')
join xmltable('for $id in tokenize($s, ",\s?") return <i>{string($id)}</i>'
passing cast('AAA, M250 , ABCD' as varchar(200)) as "s"
columns token varchar(200) path '.') x on x.token=t.ALERT_TYPE
;
(根据需要)那样工作。这些谓词不相等。
如果要传递如下这样的逗号分隔的字符串,则需要一些“字符串标记器”。
WHERE
按原样运行该语句。然后,您可以使用IN (cast(? as varchar(xxx)))
子句取消注释该字符串,并注释掉其余部分以查看您尝试执行的操作。
P.S .:
您得到的错误可能是因为您未指定参数的数据类型(您未使用诸如ALERT_TYPE
之类的信息,并且db2编译器假定其长度等于{{1}的长度)。 }表达式(4个字节)。