真的对 sql 注入感到困惑

Really confused about sql injection

获得有关可能导致 sql 注入的错误的详细信息页面

URL 编码 GET 输入 classid 设置为 1 AND 3*2*1=6 AND 608=608

执行的测试:

这是可能导致问题的源代码:

if (!string.IsNullOrEmpty(Request.QueryString["classid"]))
{
    string tSql = @" SELECT  [Award_ID],[Award_Name],[Award_Info],[Award_Pic],[Award_Num],[Award_MoneyCost],[Award_MoneyGet],[Award_Type],[Award_AddDate],[Award_Hot],[Award_OnLineTime],[AwardProP],[PrizeSlidePic],[PrizeDetailPic],[PrizeBigSlidePic],[IsTop],[ClassID] FROM  dbo.Web_Award WHERE ClassID={0} ";

    DataTable data = DbSession.Default.FromSql(string.Format(tSql, Request.QueryString["classid"])).ToDataTable();

    if (data.Rows.Count > 0)
    {
        rptList.DataSource = data;
        rptList.DataBind();
    }
}
else
{
    string tSql = @" SELECT  [Award_ID],[Award_Name],[Award_Info],[Award_Pic],[Award_Num],[Award_MoneyCost],[Award_MoneyGet],[Award_Type],[Award_AddDate],[Award_Hot],[Award_OnLineTime],[AwardProP],[PrizeSlidePic],[PrizeDetailPic],[PrizeBigSlidePic],[IsTop],[ClassID] FROM  dbo.Web_Award  ";

    DataTable data = DbSession.Default.FromSql(tSql).ToDataTable();

    if (data.Rows.Count > 0)
    {
        rptList.DataSource = data;
        rptList.DataBind();
    }
}

任何人都可以告诉我如何处理这个...非常感谢!

现在我已将我的代码修改为

if (!string.IsNullOrEmpty(Request.QueryString["classid"]))
        {
            //string tSql = @" SELECT  [Award_ID],[Award_Name],[Award_Info],[Award_Pic],[Award_Num],[Award_MoneyCost],[Award_MoneyGet],[Award_Type],[Award_AddDate],[Award_Hot],[Award_OnLineTime],[AwardProP],[PrizeSlidePic],[PrizeDetailPic],[PrizeBigSlidePic],[IsTop],[ClassID] FROM  dbo.Web_Award WHERE ClassID={0} ";
            string tSql = "SELECT [Award_ID],[Award_Name],[Award_Info],[Award_Pic],[Award_Num],[Award_MoneyCost],[Award_MoneyGet],[Award_Type],[Award_AddDate],[Award_Hot],[Award_OnLineTime],[AwardProP],[PrizeSlidePic],[PrizeDetailPic],[PrizeBigSlidePic],[IsTop],[ClassID] FROM dbo.Web_Award WHERE ClassID = @ClassID";
            //DataTable data = DbSession.Default.FromSql(string.Format(tSql, Request.QueryString["classid"])).ToDataTable();
            SqlConnection connection = new SqlConnection("Server=(local);Integrated Security=SSPI;database=DaysQP");
            connection.Open();
            SqlCommand command = new SqlCommand(tSql, connection);
            command.Parameters.Add(new SqlParameter("@ClassId", System.Data.SqlDbType.Int));
            command.Parameters["@ClassID"].Value = 1;
            using (SqlDataReader dr = command.ExecuteReader())
            {
                var data = new DataTable();
                data.Load(dr);
                if (data.Rows.Count > 0)
                {
                    rptList.DataSource = data;
                    rptList.DataBind();
                }
            }
            connection.Close();
        }
        else
        {
            string tSql = @" SELECT  [Award_ID],[Award_Name],[Award_Info],[Award_Pic],[Award_Num],[Award_MoneyCost],[Award_MoneyGet],[Award_Type],[Award_AddDate],[Award_Hot],[Award_OnLineTime],[AwardProP],[PrizeSlidePic],[PrizeDetailPic],[PrizeBigSlidePic],[IsTop],[ClassID] FROM  dbo.Web_Award  ";
            DataTable data = DbSession.Default.FromSql(tSql).ToDataTable();
            if (data.Rows.Count > 0)
            {
                rptList.DataSource = data;
                rptList.DataBind();
            }
        }

但是问题依然存在..

终于通过参数化查询解决了问题!

if (!string.IsNullOrEmpty(Request.QueryString["classid"]))
{   
    int number;
    bool result = Int32.TryParse(Request.QueryString["classid"], out number);

if (result == false)
{
    return;
}

//string tSql = @" SELECT  [Award_ID],[Award_Name],[Award_Info],[Award_Pic],[Award_Num],[Award_MoneyCost],[Award_MoneyGet],[Award_Type],[Award_AddDate],[Award_Hot],[Award_OnLineTime],[AwardProP],[PrizeSlidePic],[PrizeDetailPic],[PrizeBigSlidePic],[IsTop],[ClassID] FROM  dbo.Web_Award WHERE ClassID={0} ";
string tSql = "SELECT [Award_ID],[Award_Name],[Award_Info],[Award_Pic],[Award_Num],[Award_MoneyCost],[Award_MoneyGet],[Award_Type],[Award_AddDate],[Award_Hot],[Award_OnLineTime],[AwardProP],[PrizeSlidePic],[PrizeDetailPic],[PrizeBigSlidePic],[IsTop],[ClassID] FROM dbo.Web_Award WHERE ClassID = @ClassID";
 //DataTable data = DbSession.Default.FromSql(string.Format(tSql, Request.QueryString["classid"])).ToDataTable();

SqlConnection connection = (SqlConnection)DbSession.Default.CreateConnection();
//SqlConnection("Server=(local);Integrated Security=SSPI;database=DaysQP");
connection.Open();
SqlCommand command = new SqlCommand(tSql, connection);
command.Parameters.Add(new SqlParameter("@ClassId", System.Data.SqlDbType.Int));
command.Parameters["@ClassID"].Value = number;
using (SqlDataReader dr = command.ExecuteReader())
{
    var data = new DataTable();
    data.Load(dr);
    if (data.Rows.Count > 0)
    {
        rptList.DataSource = data;
        rptList.DataBind();
    }
}
connection.Close();

}

注入的潜力将在这里:

string tSql = @" SELECT  [Award_ID],[Award_Name],[Award_Info],[Award_Pic],[Award_Num],[Award_MoneyCost],[Award_MoneyGet],[Award_Type],[Award_AddDate],[Award_Hot],[Award_OnLineTime],[AwardProP],[PrizeSlidePic],[PrizeDetailPic],[PrizeBigSlidePic],[IsTop],[ClassID] FROM  dbo.Web_Award WHERE ClassID={0} ";
DataTable data = DbSession.Default.FromSql(string.Format(tSql, Request.QueryString["classid"])).ToDataTable();

您希望查询 return Web_Award table 条记录,其 classId 匹配 Request.QueryString["classid"]

如果 Request.QueryString["classid"] 的值类似于:

会发生什么
1 or 1=1

则查询变为:

select award_id,..... from web_awards where classId=1 or 1=1

然后您最终 return 获取您从未想过的数据。

本质上,这就是 sql 注入,您可能会阅读更多相关内容。使用存储过程或参数化查询可防止此类攻击。