當匯入/決議平面檔案和分隔資料(我們SqlBulkCopy用于這些)時,我們最終會得到一個帶有 DATA_KEY 和 DATA_VAL 列的表。[編輯]忘了提到這個表是 .net crl 的作業表,僅用于決議各種入站資料。要將資料從此作業表加載到生產表中,我們然后使用動態查詢來對資料進行 PIVOT,如下所示:
DECLARE @sqlCommand varchar(MAX)
DECLARE @columnList varchar(max)
SELECT
@columnList = STUFF((SELECT DISTINCT',MIN(CASE DATA_KEY WHEN ''' DATA_KEY ''' THEN DATA_VAL END) AS ' QUOTENAME(DATA_KEY)
FROM PARSED_DATA
FOR XML PATH ('')), 1, 1, '')
SET @sqlCommand = 'SELECT ROW_NUMBER() OVER(ORDER BY KEYID,PARENT_POS) AS ROWID, ' @columnList ' FROM PARSED_DATA
這作業正常,但帶來了可能的 SQL 注入問題。顯然,這是一個連接字串,因此 DATA_KEY 和 DATA_VAL 可能會受到注入。當我查看 DATA_KEY 欄位時,似乎注入起作用的唯一方法是如果攻擊者知道這是在 CASE 陳述句中——也就是說,注入的代碼必須正確地結束 CASE 陳述句,否則整個查詢都會失敗。同樣,如果注入沒有正確結束 CASE 陳述句,則 DATA_VAL 欄位將使整個查詢失敗。
我在這里正確嗎?還是我錯過了一些明顯的東西?此外,在 DATA_KEY 用作列名的地方我們是否容易受到影響?QUOTENAME 使值成為有效的 SQL 識別符號;那里可以注射嗎?
只是想確保所有基礎都被覆寫;歡迎提出意見和建議!
uj5u.com熱心網友回復:
我可以看到幾個問題:
- 您也應該
QUOTENAME在樞軸CASE運算式上使用。使用''''作為此第二個引數,以獲得''作為分隔符 FOR XML應該用于.value取消轉義 XML 字符- 的第三個引數
STUFF是長度。為確保它始終正確,請使用@separator變數 - 動態 SQL 應該在
nvarchar(max) DISTINCT計算欄位的性能可能很慢,在派生表/子查詢中先分組可能更明智
DECLARE @separator nvarchar(10) = ',';
DECLARE @columnList nvarchar(max) = STUFF(
(SELECT @separator 'MIN(CASE DATA_KEY WHEN ' QUOTENAME(DATA_KEY, '''') ' THEN DATA_VAL END) AS ' QUOTENAME(DATA_KEY)
FROM (SELECT DISTINCT DATA_KEY FROM PARSED_DATA) pd
FOR XML PATH (''), TYPE
).value('text()[1]','nvarchar(max)'), 1, LEN(@separator), '');
你說你正在使用它來生成一個INSERT陳述句,所以你還應該檢查列名sys.columns
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/387483.html
標籤:sql-server 查询语句 动态-sql
上一篇:基于LIKE詞連接表
下一篇:將資料庫架構資訊生成為XML
