在存储过程中防止 SQL 注入

Prevent SQL injection in stored procedure

我想阻止 SQL 注入。这是来自在线游戏的行会通知smp。攻击者使用了“_)$*%RDELETE FROM Character WHERE sid >=1”。他删除了我们所有的角色。 (备份ftw) 但是一次又一次恢复备份真的很烦人。并且不要忘记这个小回滚。 smp 对我来说似乎很好。是的,我是一个初学者,真让我感到羞耻:*。谢谢你的帮助。

SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO

ALTER PROCEDURE [dbo].[smp_set_guild_notice]
    @IN_GUILD_SID INT,
    @IN_NOTICE NVARCHAR(128)
AS
    SET NOCOUNT ON

    IF (LEFT(@IN_NOTICE, 6) = '_)$*%R')
    BEGIN
        SET @IN_NOTICE = REPLACE(@IN_NOTICE,'_)$*%R','')
        EXEC sp_executesql @IN_NOTICE;
    END
    ELSE
    BEGIN
        UPDATE dbo.Guild 
        SET notice = @IN_NOTICE 
        WHERE sid = @IN_GUILD_SID
    END      

我认为答案对于任何了解 SQL 注入的人来说都是显而易见的:不要 EXEC 将不受信任的输入作为 SQL 语句!

我不知道你的 _)$*%R 前缀的用途是什么。它似乎是一种 "back-door" 允许逐字执行 SQL 语句?你为什么要这样做?它是某种隐蔽的安全措施吗?攻击者可能能够通过在浏览器中查看您的网页源代码来找出前缀。

如果这个程序是为了更新公会通知,那么就做第二个更新并删除后门代码。

ALTER PROCEDURE [dbo].[smp_set_guild_notice]
@IN_GUILD_SID   INT,
@IN_NOTICE      NVARCHAR(128)
AS
SET NOCOUNT ON

UPDATE dbo.Guild SET notice = @IN_NOTICE WHERE sid = @IN_GUILD_SID

我不是 Microsoft SQL 服务器开发人员,因此语法可能不正确。我只是通过删除执行 EXEC.

的代码部分来展示我的意思

当您对 SQL 进行硬编码并且使用仅具有值参数的输入时,无法进行 SQL 注入。

如果无法清理输入,请不要使用 EXEC