Xin lỗi vì câu hỏi dài nhưng điều này chứa tất cả các câu lệnh SQL mà tôi đã sử dụng để kiểm tra kịch bản để hy vọng nó rõ ràng như những gì tôi đang làm.Máy chủ SQL - Bảng PIVOT động - SQL Injection
Tôi đang xây dựng một số SQL động để tạo bảng PIVOT trong SQL Server 2005.
Dưới đây là mã để thực hiện việc này. Với các lựa chọn khác nhau cho thấy dữ liệu thô các giá trị sử dụng GROUP BY và các giá trị trong PIVOT như tôi muốn chúng.
BEGIN TRAN
--Create the table
CREATE TABLE #PivotTest
(
ColumnA nvarchar(500),
ColumnB nvarchar(500),
ColumnC int
)
--Populate the data
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'X', 1)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'Y', 2)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'Z', 3)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'X', 4)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'Y', 5)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('B', 'Z', 6)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('B', 'X', 7)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('B', 'Y', 8)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('B', 'Z', 9)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('C', 'X', 10)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('C', 'Y', 11)
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('C', 'Z', 12)
--The data
SELECT * FROM #PivotTest
--Group BY
SELECT
ColumnA,
ColumnB,
SUM(ColumnC)
FROM
#PivotTest
GROUP BY
ColumnA,
ColumnB
--Manual PIVOT
SELECT
*
FROM
(
SELECT
ColumnA,
ColumnB,
ColumnC
FROM
#PivotTest
) DATA
PIVOT
(
SUM(DATA.ColumnC)
FOR
ColumnB
IN
(
[X],[Y],[Z]
)
) PVT
--Dynamic PIVOT
DECLARE @columns nvarchar(max)
SELECT
@columns =
STUFF
(
(
SELECT DISTINCT
', [' + ColumnB + ']'
FROM
#PivotTest
FOR XML PATH('')
), 1, 1, ''
)
EXEC
('
SELECT
*
FROM
(
SELECT
ColumnA,
ColumnB,
ColumnC
FROM
#PivotTest
) DATA
PIVOT
(
SUM(DATA.ColumnC)
FOR
ColumnB
IN
(
' + @columns + '
)
) PVT
')
--The data again
SELECT * FROM #PivotTest
ROLLBACK
Bất cứ khi nào tôi tạo ra bất kỳ SQL động nào, tôi luôn nhận thức được các cuộc tấn công SQL Injection. Do đó tôi đã thêm dòng sau đây với các câu lệnh INSERT khác.
INSERT INTO #PivotTest (ColumnA, ColumnB, ColumnC) VALUES('A', 'FOO])) PVT; DROP TABLE #PivotTest;SELECT ((GETDATE()--', 1)
Khi tôi chạy SQL, thấp và nhìn, phần EXEC thả bảng #PivotTest do đó làm cho SELECT cuối cùng thất bại.
Vì vậy, câu hỏi của tôi là, có ai biết cách để thực hiện một PIVOT động mà không mạo hiểm các cuộc tấn công SQL Injection không?
1) mẫu thử nghiệm của tôi là một trong những đơn giản. Các cột thực tế là nvarchar (max). Hiện tại chúng tôi không có dữ liệu về kích thước và dữ liệu sẽ được sử dụng cho PIVOT hiếm khi có thể lên đến 100 vì vậy tôi có thể thực hiện một lệnh cắt bắt buộc trong trường hợp này! Ý tưởng tuyệt vời. 2) Tôi đã suy nghĩ về '[' và ']'. Tôi bị cám dỗ để loại bỏ tất cả các dấu ngoặc vuông khỏi dữ liệu và chỉ có điều đó như là một hạn chế của chức năng này. 3) Những người duy nhất có thể thêm dữ liệu này được gọi là "Người dùng siêu", tuy nhiên, điều này là không đủ để tôi yên tâm. –
QUOTENAME! Lần đầu tiên tôi nhìn thấy nó! Hoàn hảo! Điều này hoàn toàn giải quyết được vấn đề. Tôi đã thêm QUOTES theo cách thủ công.Nếu tôi loại bỏ điều này và làm điều đó bằng cách sử dụng QUOTENAME nó sẽ vô hiệu hóa bất kỳ SQL trong lĩnh vực đó! CẢM ƠN BẠN! –