You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态SQL存储过程是否存在SQL注入风险?如何查看sp_executesql最终执行语句

动态SQL存储过程usp_SearchEntities问题解答

1. 该存储过程是否存在SQL注入风险?

风险与否完全取决于动态SQL的拼接方式:

  • 若采用参数化传递变量(通过sp_executesql的参数列表传递,而非直接拼接变量值到SQL字符串),则几乎无注入风险。示例:
    DECLARE @sql NVARCHAR(MAX) = N'SELECT * FROM Entities WHERE Name = @Name';
    EXEC sp_executesql @sql, N'@Name NVARCHAR(100)', @Name = @SearchValue;
    
    这种模式下,SQL Server会将参数值作为独立数据处理,不会解析为SQL语句的一部分,能彻底规避注入攻击。
  • 若直接拼接变量值到SQL字符串(比如用+连接变量),则必然存在注入风险。示例:
    DECLARE @sql NVARCHAR(MAX) = N'SELECT * FROM Entities WHERE Name = ''' + @SearchValue + '''';
    EXEC sp_executesql @sql;
    
    攻击者可构造恶意参数值(如' OR 1=1 --),拼接后会生成破坏原有逻辑的SQL语句,导致数据泄露或篡改。

核心判断标准:是否始终通过参数化方式传递动态SQL中的变量,而非直接字符串拼接。

2. 如何查看sp_executesql执行时已替换参数值的最终查询语句?

PRINT @sql仅能输出含参数占位符的模板语句,以下几种方法可查看实际执行的完整语句:

  • SQL Server Profiler:开启跟踪后,选择SQL:BatchCompleted或RPC:Completed事件,事件详情中会显示替换参数值后的完整执行语句。
  • Extended Events:创建针对sql_statement_completed事件的会话,捕获statement字段,该字段会记录实际执行的完整SQL(包含参数值)。
  • 手动模拟参数替换:参数较少时,可自行编写代码将参数值替换到模板SQL中,示例:
    DECLARE @sql NVARCHAR(MAX) = N'SELECT * FROM Entities WHERE Name = @Name';
    DECLARE @Name NVARCHAR(100) = 'TestEntity';
    SET @sql = REPLACE(@sql, '@Name', QUOTENAME(@Name, ''''));
    PRINT @sql;
    
    注意:此方法仅适用于简单场景,含特殊字符的参数需额外处理转义逻辑。
  • 动态管理视图查询:通过sys.dm_exec_query_stats和sys.dm_exec_sql_text查找最近执行的语句,示例:
    SELECT 
        st.text
    FROM 
        sys.dm_exec_query_stats qs
    CROSS APPLY 
        sys.dm_exec_sql_text(qs.sql_handle) st
    WHERE 
        st.text LIKE '%usp_SearchEntities%';
    
    需注意筛选匹配目标查询的记录,确保结果准确。

内容的提问来源于stack exchange,提问作者lifeisajourney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 08:05:58