[英]How to fix Inline C# query that is prone to SQL injection
以下是我為獲取給定 where 子句的簡單最大值而編寫的查詢。
唯一的問題是它必須通過 veracode 掃描來確定查詢是否容易受到任何 SQL 注入。
這是我的查詢
string strconnectionString = @Data Source = xxx\server; Initial Catalog =DBname;
這些是用戶輸入我現在只是硬編碼
private DateTime? GetFirmsLastDate()
{
// My user inputs hardcoded for now
string tableName = "abc";
string columnName = "CalculationTable";
string filterColumn = "CalcValue";
string firmName = "Bank1";
using(SqlConnection connection = new SqlConnection(strconnectionString)
{
using(Sqlcommand cmd = new SqlCommand())
{
cmd.Connection = connection;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = String.Format(@"Select MAX(K.{3}) FROM {1} K WHERE K.{2} ={0}" ,
Sanitizer.GetSafeHtmlFragment(firmName),
Sanitizer.GetSafeHtmlFragment(tableName),
Sanitizer.GetSafeHtmlFragment(filterColumn),
Sanitizer.GetSafeHtmlFragment(column)
connection.Open();
object dateVal = cmd.ExecuteScalar();
return (dataVal != DBNull.Value) : DateTime.Parse(dateVal.ToString()) : null;
}
}
}
為什么我必須使用內聯查詢是TableName
。 它是一個文本框,用戶可以在其中輸入表名。 為此,我無法將tableName
指定為參數,我必須在傳遞SqlCommand
時准備我的語句。
感謝您的時間。
我能想到的“安全”執行此操作的唯一方法是將內聯查詢更改為對存儲過程的參數化調用,然后在那里優雅地處理對象名稱。 但是,這要求被檢查的列始終具有相同的數據類型(在這種情況下,我假設為int
):
CREATE PROC TableMaxCount @Table sysname, @Column sysname, @Value int AS
BEGIN
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT MAX(' + QUOTENAME(@Column) + NCHAR(13) + NCHAR(10) +
N'FROM ' + QUOTENAME(@Table) + NCHAR(13) + NCHAR(10) +
N'WHERE ' + QUOTENAME(@Column) + N' = @Value;';
EXEC sp_executesql @SQL, N'@Value int', @Value = @Value;
END
但是,如果用戶輸入的值不是讀取的表或列,則會產生錯誤。 如果不需要,並且您想驗證對象名稱,則可以執行以下操作:
CREATE PROC TableMaxCount @Table sysname, @Column sysname, @Value int AS
BEGIN
DECLARE @SQL nvarchar(MAX);
SELECT @SQL = N'SELECT MAX(' + QUOTENAME(c.[name]) + NCHAR(13) + NCHAR(10) +
N'FROM ' + QUOTENAME(t.[name]) + NCHAR(13) + NCHAR(10) +
N'WHERE ' + QUOTENAME(c.[name]) + N' = @Value;'
FROM sys.tables t
JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE t.[name] = @Table
AND c.[name] = @Column
AND s.[name] = N'dbo'; --Assumes always dbo schema
EXEC sp_executesql @SQL, N'@Value int', @Value = @Value;
END
恐怕我的 C# 充其量是很糟糕的,但是,希望您已經知道如何使用參數化代碼來調用 SQL。 如果沒有,我知道文檔確實涵蓋了它。 ( SqlCommand.Parameters 屬性)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.