gpt4 book ai didi

tsql - 如何防止 SQL 注入(inject)

转载 作者:行者123 更新时间:2023-12-04 17:12:59 24 4
gpt4 key购买 nike

我正在使用存储过程。
为了节省时间,我做了一些通用程序,使用动态sql来更新。这样的通用程序是:

CREATE PROCEDURE [dbo].[SetField]
@company_id uniqueidentifier,
@id bigint,
@field_code nvarchar(50),
@value nvarchar(50)
AS
BEGIN
DECLARE @field_name nvarchar(50)
SET @field_name = NULL
SELECT @field_name=field_name
FROM dbo.FIELD_DEFINITION
WHERE field_code=@field_code

IF @field_name IS NOT NULL
BEGIN

IF @value IS NULL OR @value=''
BEGIN
SET @value='NULL'
END
ELSE
BEGIN
IF @field_code='START_DATE' OR @field_code='END_DATE'
BEGIN
SET @value = CONVERT(datetime, @value ,103)
END
SET @value=''''+@value+''''
END

DECLARE @sql nvarchar(1000)
SET @sql = 'UPDATE dbo.TABLE '+
'SET '+@field_name+'='+@value+' '+
'WHERE company_id=''' + CAST(@company_id as nvarchar(36)) + ''' AND '+
'id='+CAST(@id as nvarchar)
EXEC(@sql)
END
END

如何使用此代码防止 sql 注入(inject)?

最佳答案

关于 SQL 注入(inject),需要记住的一个重要方面是,如果可能的话,永远不要将用户提供的值直接嵌入到 SQL 中。这并不意味着您不能使用动态 sql(尽管如果您不使用它肯定会让事情变得更容易),但它有时会变得更加危险。

在您的具体示例中,您可以保留除 @field_name 之外的所有内容的参数化。 .不幸的是,这必须直接嵌入到 SQL 中;其他所有内容都可以再次作为参数传递,因此无需担心它们的内容。

在此特定示例中,您可以做的最安全的事情如下:

if(exists (select 1 from INFORMATION_SCHEMA.Columns where TABLE_NAME = 'Table' and TABLE_SCHEMA = 'dbo' and COLUMN_NAME = @fieldName))
begin
DECLARE @sql nvarchar(1000)
SET @sql = 'UPDATE dbo.TABLE '+
'SET ' + QUOTENAME(@field_name) + '=@value ' +
'WHERE company_id=@company_id AND '+
'id=@id'

exec sp_executesql @sql,N'@id bigint, @company_id uniqueidentifier, @value nvarchar(50)',@id,@company_id,@value
end

这做了两件事:
  • 它验证表中是否确实存在具有该名称的列。如果用户将任何其他 SQL 语句嵌入到该字段中,则此检查将失败并且不会执行该语句。您也可以调用raiseerror报告错误,但我会把这个练习留给你。
  • 它将字段名称括在方括号中,以便包含空格或保留字的字段名称不会破坏语句。这对您来说可能不是问题,但如果您自己生成 SQL,这始终是一种好习惯。
  • 关于tsql - 如何防止 SQL 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4809608/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com