首页 > 代码库 > 【2017-04-20】Sql字符串注入式攻击与防御

【2017-04-20】Sql字符串注入式攻击与防御

字符串攻击 

所谓sql字符串注入式攻击就是在用户输入界面输入通过精心编制的含有某种指令的字符串,来改变C#中连接数据库要执行的sql语句,从而对数据库进行攻击性操作

技术分享

在用户输入界面输入  a‘);update Student set Sname =‘伊伊‘;--

则数据库Sname一列都讲变为  伊伊

原理:用户输入的代码将c#中的sql语句中的sname替换掉了,就变成了下边的黑客想执行的sql语句。

insert into Student values(‘"+sno+"‘,‘a‘);update Student set Sname =‘伊伊‘;--‘)

 

攻击防御

将C#中操作数据库执行的sql语句中的字符串拼接换成占位符,通过使用此占位符来进行防字符串攻击,这样,占位符所代表的的仅仅是字符串,不带有代码含义

用占位符进行防御之后不会改变表的其他内容,会将这句代码原封不动的存到数据库中而不会改变c#中的sql语句。

使用占位符时最好先清除一次,防止受到之前占位符的影响

技术分享

技术分享

 

开发项目三层架构:界面层、业务逻辑层、数据访问层

其中数据访问层分为:

1、实体类

数据库中的表映射为一个类,类名与表名一致。表中的每一列,都为该类下的成员变量和属性也就是最简单的封装

把数据库中的表名变为类的类名。

把数据库中的每一个列,变为实体类中的成员变量和属性

列名与属性名一致。成员变量名:在列名前边加上下划线

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1.App_Code
{
    public class Users
    {
        private int _Ids;

        public int Ids
        {
            get { return _Ids; }
            set { _Ids = value; }
        }
        private string _UserName;

        public string UserName
        {
            get { return _UserName; }
            set { _UserName = value; }
        }
        private string _PassWord;

        public string PassWord
        {
            get { return _PassWord; }
            set { _PassWord = value; }
        }
        private string _NickName;

        public string NickName
        {
            get { return _NickName; }
            set { _NickName = value; }
        }
        private bool _Sex;

        public bool Sex
        {
            get { return _Sex; }
            set { _Sex = value; }
        }
        private DateTime _Birthday;

        public DateTime Birthday
        {
            get { return _Birthday; }
            set { _Birthday = value; }
        }
        private string _Nation;

        public string Nation
        {
            get { return _Nation; }
            set { _Nation = value; }
        }
    }
}

2、数据访问类

将某个表的数据库操作写成一个一个方法,放入到此类中,供外部调用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;

namespace ConsoleApplication2.App_Code
{
    public class UsersData
    {
        SqlConnection conn = null;
        SqlCommand cmd = null;

        public UsersData()
        {
            conn = new SqlConnection("server=.;database=Data0216;user=sa;pwd=123");
            cmd = conn.CreateCommand();
        }

        public List<Users> SelectAll()
        {
            List<Users> list = new List<Users>();

            cmd.CommandText = "select *from Users";
            conn.Open();
            SqlDataReader dr = cmd.ExecuteReader();
            while (dr.Read())
            {
                Users u = new Users();
                u.Ids = Convert.ToInt32(dr["ids"]);
                u.UserName = dr["UserName"].ToString();
                u.PassWord = dr["PassWord"].ToString();
                u.NickName = dr["NickName"].ToString();
                u.Sex = Convert.ToBoolean(dr["Sex"]);
                u.Birthday = Convert.ToDateTime(dr["Birthday"]);
                u.Nation = dr["Nation"].ToString();

                list.Add(u);
            }
            conn.Close();
            return list;
        }


        public void Insert(Users u)
        {
            cmd.CommandText = "insert into Users values(@username,@password,@nickname,@sex,@birthday,@nation)";
            cmd.Parameters.Clear();
            cmd.Parameters.AddWithValue("@username", u.UserName);
            cmd.Parameters.AddWithValue("@password", u.PassWord);
            cmd.Parameters.AddWithValue("@nickname", u.NickName);
            cmd.Parameters.AddWithValue("@sex", u.Sex);
            cmd.Parameters.AddWithValue("@birthday", u.Birthday);
            cmd.Parameters.AddWithValue("@nation", u.Nation);

            conn.Open();
            int a= cmd.ExecuteNonQuery();
            if (a > 0) Console.WriteLine("添加数据成功");
            else Console.WriteLine("添加数据失败");
            conn.Close();
        }
    }
}

 

【2017-04-20】Sql字符串注入式攻击与防御