Pertama-tama, Anda harus TIDAK PERNAH lakukan komposisi perintah SQL pada aplikasi klien seperti ini, itu apa itu SQL Injection. (Tidak apa-apa untuk alat admin yang tidak memiliki privasinya sendiri, tetapi tidak untuk aplikasi penggunaan bersama).
Kedua, ya, panggilan parametrized ke prosedur Tersimpan lebih bersih dan lebih aman.
Namun , karena Anda perlu menggunakan SQL Dinamis untuk melakukannya, Anda tetap tidak ingin menyertakan string yang diteruskan dalam teks kueri yang dieksekusi. Sebagai gantinya, Anda ingin menggunakan string yang diteruskan untuk mencari nama aktual tabel yang harus diizinkan untuk dikueri oleh pengguna.
Berikut ini contoh sederhana yang naif:
CREATE PROC spCountAnyTableRows( @PassedTableName as NVarchar(255) ) AS
-- Counts the number of rows from any non-system Table, *SAFELY*
BEGIN
DECLARE @ActualTableName AS NVarchar(255)
SELECT @ActualTableName = QUOTENAME( TABLE_NAME )
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = @PassedTableName
DECLARE @sql AS NVARCHAR(MAX)
SELECT @sql = 'SELECT COUNT(*) FROM ' + @ActualTableName + ';'
EXEC(@SQL)
END
Beberapa orang cukup bertanya mengapa ini lebih aman. Semoga, Bobby Tables kecil dapat memperjelas ini:0
Jawaban untuk pertanyaan lainnya:
-
QUOTENAME saja tidak dijamin aman. MS mendorong kami untuk menggunakannya, tetapi mereka tidak memberikan jaminan bahwa itu tidak dapat dikalahkan oleh peretas. FYI, Keamanan sebenarnya adalah tentang jaminan. Pencarian tabel dengan QUOTENAME, adalah cerita lain, tidak bisa dipecahkan.
-
QUOTENAME tidak sepenuhnya diperlukan untuk contoh ini, terjemahan Pencarian di INFORMATION_SCHEMA saja biasanya cukup. QUOTENAME ada di sini karena merupakan bentuk keamanan yang baik untuk menyertakan solusi yang lengkap dan benar. QUOTENAME di sini sebenarnya melindungi terhadap masalah potensial yang berbeda, tetapi serupa yang dikenal sebagai injeksi laten .
Saya harus mencatat bahwa Anda dapat melakukan hal yang sama dengan Nama Kolom dinamis dan INFORMATION_SCHEMA.COLUMNS
meja.
Anda juga dapat mengabaikan kebutuhan untuk prosedur tersimpan dengan menggunakan kueri SQL berparameter (lihat di sini:https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.parameters?view=jaringan-4.8). Namun menurut saya, prosedur tersimpan menyediakan fasilitas keamanan yang lebih mudah dikelola dan tidak rawan kesalahan untuk kasus seperti ini.