我有Select Insert语句,我想知道是否应该阻止我的代码从SQL注入。此代码使用BULK Insert
和TEMP TABLE
。我以前从来没有使用过这个,如果在这种情况下我可以/应该使用cfqueryparam
,或者在这种情况下我还能申请其他什么,我就不熟悉了?这是我的代码:
<cfquery datasource="testDB" name="InsertBulk">
IF OBJECT_ID('tempdb..##TEMP_TBL') IS NOT NULL DROP TABLE ##TEMP_TBL;
CREATE TABLE ##TEMP_TBL (#cols#)
BULK INSERT ##TEMP_TBL
FROM 'D:\myFiles\myTXT.txt'
WITH (
FIELDTERMINATOR = '\t',
ROWTERMINATOR = '\n'
)
</cfquery>
<cfquery datasource="testDB" name="InsertUpdate">
INSERT INTO myRecords(
FIRST_NAME,
LAST_NAME,
GENDER,
DOB
)
SELECT
CASE WHEN LEN(LTRIM(RTRIM(FIRST_NAME))) <> 0 OR FIRST_NAME <> 'NULL' THEN FIRST_NAME END,
CASE WHEN LEN(LTRIM(RTRIM(LAST_NAME))) <> 0 OR LAST_NAME <> 'NULL' THEN LAST_NAME END,
CASE WHEN LEN(LTRIM(RTRIM(GENDER))) <> 0 OR GENDER <> 'NULL' THEN GENDER END,
CASE WHEN LEN(LTRIM(RTRIM(BIRTH_DATE))) <> 0 OR BIRTH_DATE <> 'NULL' THEN BIRTH_DATE END
FROM ##TEMP_TBL AS TempInsert
WHERE NOT EXISTS (
SELECT *
FROM myRecords AS Dups
WHERE Dups.userID = TempInsert.user_ID
)
UPDATE Records
SET
Records.FIRST_NAME = CASE WHEN LEN(LTRIM(RTRIM(Temp.FIRST_NAME))) <> 0 OR Temp.FIRST_NAME <> 'NULL' THEN Temp.FIRST_NAME END,
Records.LAST_NAME = CASE WHEN LEN(LTRIM(RTRIM(Temp.LAST_NAME))) <> 0 OR Temp.LAST_NAME <> 'NULL' THEN Temp.LAST_NAME END,
Records.GENDER = CASE WHEN LEN(LTRIM(RTRIM(Temp.GENDER))) <> 0 OR Temp.GENDER <> 'NULL' THEN Temp.GENDER END,
Records.DOB = CASE WHEN LEN(LTRIM(RTRIM(Temp.BIRTH_DATE))) <> 0 OR Temp.BIRTH_DATE <> 'NULL' THEN Temp.BIRTH_DATE END,
FROM myRecords AS Records
INNER JOIN ##TEMP_TBL AS Temp
ON Records.userID = Temp.user_ID
WHERE Records.userID = Temp.user_ID
</cfquery>
我已经使用批量处理我的问题,因为我试图避免使用cfloop
并创建多个INSERT/UPDATE
语句。
答案 0 :(得分:1)
不,你不能在这里使用cfqueryparam
。但是,除#cols#
之外,您可能不需要这些语句。
CFQueryparam
旨在防止 literals (即简单的字符串,日期等)作为sql命令执行。 SELECT语句不需要保护,因为它不包含任何可以解释为命令的文字。
上述语句中可能存在的一个风险是#cols#
变量,它似乎代表了列名列表。对象名称(列名,表名等)必须被解释为命令的一部分。使用cfqueryparam
旨在防止这种情况发生。因此它不能用于保护#cols#
变量。 如果该变量是客户端提供的,您必须自己进行任何清理。
请记住,即使将数据保存到数据库,仍然存在风险。即使您使用cfqueryparam
,仍可以在数据库中插入恶意值。 CFQueryparam
不会神奇地使输入值安全。它只是防止执行值中的任何恶意命令(并且仅在当前语句中)。它不会阻止INSERT或UPDATE将值保存到数据库,并在以后冒险。对于使用任何类型的动态SQL的应用程序,存储的值仍可能通过second order SQL injection:
提交的值包含时,会发生二阶SQL注入 存储而不是立即执行的恶意命令。 在某些情况下,应用程序可能正确编码SQL语句 并将其存储为有效的SQL。然后,该应用程序的另一部分 没有控制来防止SQL注入可能会执行 存储的SQL语句。这种攻击需要更多的知识 提交的值稍后使用....
因此,始终使用cfqueryparam并避免不使用绑定变量的动态SQL非常重要。例如,在CF中,避免使用PreserveSingleQuotes,或者在SQL Server存储过程中,避免使用EXEC and use sp_executeSQL if needed。