保護這個函數免於SQL注入的方法是什麼?
P粉573943755
P粉573943755 2023-11-07 22:03:43
0
2
738

public static bool TruncateTable(string dbAlias, string tableName)
{
    string sqlStatement = string.Format("TRUNCATE TABLE {0}", tableName);
    return ExecuteNonQuery(dbAlias, sqlStatement) > 0;
}

P粉573943755
P粉573943755

全部回覆(2)
P粉434996845

據我所知,不能使用參數化查詢來執行DDL語句/指定表名,至少在Oracle或Sql Server中不能。如果我必須有一個瘋狂的 TruncateTable 函數,並且必須能夠避免 SQL 注入,那麼我會做的就是建立一個預存程序來檢查輸入是否是可以安全截斷的表。

-- Sql Server specific!
CREATE TABLE TruncableTables (TableName varchar(50))
Insert into TruncableTables values ('MyTable')

go

CREATE PROCEDURE MyTrunc @tableName varchar(50)
AS
BEGIN

declare @IsValidTable int
declare @SqlString nvarchar(50)
select @IsValidTable = Count(*) from TruncableTables where TableName = @tableName

if @IsValidTable > 0
begin
 select @SqlString = 'truncate table ' + @tableName
 EXECUTE sp_executesql @SqlString
end
END
P粉738346380

對抗 SQL 注入的最常見建議是使用 SQL 查詢參數(該執行緒上的幾個人都建議這樣做)。

在這種情況下這是錯誤的答案。您無法在 DDL 語句中對錶名使用 SQL 查詢參數。

SQL 查詢參數只能用來取代 SQL 運算式中的文字值。這是每個 SQL 實作的標準。

當您有表名時,我建議防止 SQL 注入是根據已知表名清單驗證輸入字串。

You can get a list of valid table names from the INFORMATION_SCHEMA:

#
SELECT table_name 
FROM INFORMATION_SCHEMA.Tables 
WHERE table_type = 'BASE TABLE'
  AND table_name = @tableName

現在您可以將輸入變數作為 SQL 參數傳遞給此查詢。如果查詢未傳回任何行,則您知道輸入無效,無法用作表。如果查詢返回一行,則它匹配,因此您可以更放心地使用它。

您也可以根據您定義為可以讓應用程式截斷的特定表格清單來驗證表格名稱,例如 @John Buchanan 建議

Even after validating that tableName exists as a table name in your RDBMS, I would also suggest delimiting the table name, just in case you use table names with spaces or special characters, In Microsoft SQL Server, the default identifier delimiters are square brackets:

string sqlStatement = string.Format("TRUNCATE TABLE [{0}]", tableName);

Now you're only at risk for SQL injection if tableName matches a real table, and you actually use square brackets in the names of your tables!

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板