如何防止SQL注入
我正在使用存储过程。 为了节省时间,我做了一些通用的程序,使用动态sqlin命令来更新。这样的通用过程是:
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 注入?
I am using stored procedures.
In order to save time, I made some generic procedures that uses dynamic sqlin order to update. Such generic procedure is:
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
How can I prevent sql injection with this code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你说:
如果您先询问,我们可以节省时间并建议这样做...
You said:
If you'd asked first, we could have saved time and suggested this...
关于 SQL 注入需要记住的一个重要方面是,如果可能的话,您永远不应该将用户提供的值直接嵌入到 SQL 中。这并不意味着您不能使用动态 sql(尽管如果您不使用它肯定会使事情变得更容易),但它有时确实会变得更加危险。
在您的具体示例中,您可以保留除
@field_name
之外的所有内容的参数化。不幸的是,这必须直接嵌入到 SQL 中;其他所有内容都可以再次作为参数传递,因此无需担心它们的内容。在此特定示例中,您可以执行的最安全的操作如下:
这会执行两件事:
raiseerror
来报告错误,但我会将这个练习留给您。The important aspect to remember about SQL injection is that means that, if at all possible, you should never embed user-supplied values directly into your SQL. This doesn't mean that you can't use dynamic sql (though it definitely makes things easier if you don't), but it does become more dangerous at times.
In your specific example, you can keep the parameterization of everything except
@field_name
. This, unfortunately, must be embedded directly into the SQL; everything else can be passed as a parameter again, so there's no need to worry about their content.The safest thing that you can do in this specific example is the following:
This does two things:
raiseerror
to report the error, but I'll leave that exercise up to you.在您致电 SP 之前,我会开始寻找防止 sql 注入攻击的方法。请小心从查询字符串或表单数据拼凑而成的动态 SQL 字符串。使用 SqlCommand 对象。
编辑:
作为对评论的回应,这里很好地解释了参数化查询(SqlCommand 查询)如何帮助防止 SQL 注入。
来自 http://forums.asp.net/t/1568268.aspx:
.. .占位符 - @Id - 已成为硬编码 SQL 的一部分。在运行时,查询字符串提供的值与硬编码的 SQL 一起传递到数据库,数据库在尝试将参数值绑定到该字段时将检查 ProductID 字段。这确保了强类型的水平。如果参数值不是数据库字段的正确类型(字符串或超出字段类型范围的数字),数据库将无法将其转换为正确的类型,并将拒绝它。如果目标字段数据类型是字符串(char、nvarchar 等),则参数值将自动“字符串化”,其中包括转义单引号。它不会构成要执行的 SQL 语句的一部分。
I would start looking at ways to prevent sql injection attacks before you ever call the SP. Be careful with dynamic SQL strings pieced together from querystring or form data. Use a SqlCommand object.
Edit:
In response to the comment, here is a nice explanation of how parameterized queries (SqlCommand queries) help prevent SQL injection.
From http://forums.asp.net/t/1568268.aspx:
...The placeholder - @Id - has become part of the hardcoded SQL. At runtime, the value provided by the querystring is passed to the database along with the hardcoded SQL, and the database will check the ProductID field as it attempts to bind the parameter value to it. This ensures a level of strong typing. If the parameter value is not the right type for the database field (a string, or numeric that's out of range for the field type), the database will be unable to convert it to the right type and will reject it. If the target field datatype is a string (char, nvarchar etc), the parameter value will be "stringified" automatically, which includes escaping single quotes. It will not form part of the SQL statement to be executed.