Fortify C# 中的参数化 SQL 注入

Parameterized SQL Injection in Fortify C#

如果我执行以下 SQL 命令,我会得到一个带有 SQL 注入的 Fortify 结果(注意 AddCommand 方法接受一个字符串)

internal void AddCommand()
{
    string cmtTxt = "SELECT * from Users WHERE @ID = 1";
    if (m_dbCon != null && !string.IsNullOrEmpty(cmdTxt))
    {
        m_dbCmd = new SqlCommand(cmdTxt, m_dbCon);
    }
}

如果我执行以下方法,SQL 注入发现就会消失。将 SQL 字符串作为参数传递与硬编码字符串有什么区别?

internal void AddCommand()
{
    if (m_dbCon != null)
    {
        m_dbCmd = new SqlCommand("SELECT * from Users WHERE @ID = 1", m_dbCon);
    }
}

我这样建立参数:

    internal void AddCmdParam(string param, string value)
    {
        if (m_dbCmd != null && !string.IsNullOrEmpty(param) && value != null && Utilities.ValidParameter(param))
        {
            m_dbCmd.Parameters.Clear();
            m_dbCmd.Parameters.Add(param, SqlDbType.NVarChar, 100);
            m_dbCmd.Parameters[param].Value = value;
        }
    }

很简单,第一段代码就是SQL注入漏洞的定义。您正在获取一个未知的字符串并执行它。例如,假设参数包含字符串 DROP DATABASE yourDb;。执行那会很糟糕。

第二个不是因为标准库转义了您使用参数传入的任何字符串,因此它不会允许 SQL 注入攻击发生。