Ado.net 三[SQL注入,DataAdapter,sqlParameter,DataSet]

1.SQL注入:SQL注入攻击是web应用程序的一种安全漏洞,可以将不安全的数据提交给运用程序,使应用程序在服务器上执行不安全的sql命令。使用该攻击可以轻松的登录运用程序。

例如:该管理员账号密码为xiexun,该sql的正确语句应该为:

select * from Users where userName=‘xiexun‘

如果在没有做任何处理的情况下,在登录名文本框中输入(xuxian‘ delete users--),单击"登录"按钮之后,相当于传了两句sql语句,一句执行查询之后,另外一句执行delete users之后整个表就没数据了,这样网站相当的不安全。

select * from Users where userName=‘xiexun‘  delete users--sql语句的注释,相当于把后面注释了

解决办法:

①.通过@传参的方式[存储过程也是通过@传参],sqlParameter方法

eg:

 public string Getswhere()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("select ID,username,PWD,loginname,qq,classname from Users  where 1=1");
            //获取到它的用户名
            string username = TxtUserName.Text.Trim();
            if (!string.IsNullOrEmpty(username))
            {
                //sb.Append(string.Format("and username=‘{0}‘", username));
                //防SQL注入,通过@传参的方式
                sb.Append(string.Format("and [email protected]"));
                //怎么把值传进去,通过sqlParameter数组
                //SqlParameter[] para = new SqlParameter[]
                //{
                //    //创建一个SqlParameter对象(第一个传名称,第二个传值)
                //    new SqlParameter("@username",username)
                //};
                // para[0]表示数组对象的第一个里面添加
                //para[0] = new SqlParameter("@username",username);                 para.Add(new SqlParameter("@username", username));            }
            if(ddlsclass.SelectedIndex>0)
            {
                //sb.Append(string.Format("and ClassName=‘{0}‘", ddlsclass.SelectedValue));
                sb.Append(string.Format("and [email protected]"));
                //para[1] = new SqlParameter("@ClassName",ddlsclass.SelectedValue);                para.Add(new SqlParameter("@ClassName", ddlsclass.SelectedValue));
            }
            return sb.ToString();
        }

List<SqlParameter> para = new List<SqlParameter>();

//我们把它放在list<>里,就有add方法

private void openDB()
         {
          con = new SqlConnection(conStr);
          con.Open();//和数据库建立起了连接
          //我们单独把这两句话封装起来直接调用就好
         }
        //页面一运行就执行这里面的内容
        protected void Page_Load(object sender, EventArgs e)
        {
          BindUser();
        }

       public void BindUser()
        {
            try
            {
                openDB();
                //得到sql语句
                //string sql = "select loginid,name,loginpwd,address,ClassName,mail from Users";
                string sql = Getswhere();
                //执行sql语句
                using (cmd = new SqlCommand(sql, con))
                //对象有了,我们要通过对象去执行sql语句
                {
                    //调用它,通过遍历加到cmd里面去,我们把下面的值给cmd
                    //如果它里面有内容,我们就对它做一个循环
                    if (para.Count() > 0)
                    {
                        foreach(var p in para)
                        {
                            cmd.Parameters.Add(p);
                        }
                    }
                    using (dr = cmd.ExecuteReader())
                    {
                        IdGridView.DataSource = dr;
                        IdGridView.DataBind();
                    }
                }
            }
            catch
            {
                Response.Write("网站正在维护中.......!");
            }
        }

这里,我们简单用一个图描述一下它的运行原理:前面的是没有通过@传参直接通过cmd与数据库交互的结果,不安全;后面一种是加了"Parameter"

我们现在是把这个值new SqlParameter("@username",username)给sqlParameter数组,sqlparameter给cmd,cmd再执行,这样就可以避免SQL注入。

2.DataAdapter数据适配器

①.工作原理:DataAdapter数据适配器相当于中间环节[中间人]

ⅰ.前端页面委托数据适配器去实现和数据库的交互;

ⅱ.数据库交互之后,再通过数据库适配器再把数据放内存里;

ⅲ.然后我们的网页直接对内存里的东西读和写。(读的话可以直接读,写的话要再通过适配器把它加进去),这样数据库处于非正常连接的情况下也可以操作数据。

而之前的写法:

1.前端页面要和数据库交互,首先要建立起连接(数据库连接);

2.用完之后要释放资源

最大的好处就是:没有必要每一个页面都要与数据库进行连接,降低了数据库的压力。

②用数据适配器做一个查询[在程序中加存储过程]

<div>
          <asp:GridView ID="IdGridView" runat="server" AutoGenerateColumns="False">
            <Columns>
                <asp:BoundField DataField="id" HeaderText="ID" />
                <asp:BoundField DataField="username" HeaderText="用户名" />
                <asp:BoundField DataField="PWD" HeaderText="密码" />
                <asp:BoundField DataField="loginname" HeaderText="姓名" />
                <asp:BoundField DataField="qq" HeaderText="QQ" />
                <asp:BoundField DataField="classname" HeaderText="班级" />
                <asp:TemplateField HeaderText="详情">
                    <ItemTemplate>
                        <a href="UserInfo.aspx?id=<%#Eval("ID") %>" target="_blank">详情</a>
                        <%--<a href=‘UserInfo.aspx?userid=<%#Eval("UserId") %>‘ target="_blank">详情</a
                       <%-- <a href="one.aspx?">详情</a>--%>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    </div>
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace _20160520
{
    public partial class egDataAp : System.Web.UI.Page
    {
        private string conStr = ConfigurationManager.ConnectionStrings["mySchool"].ToString();
        SqlConnection con = null;//相当于是电话
        SqlCommand cmd = null;//执行sql语句
        SqlDataReader dr = null;//用于储存查询结果
        //首先创建一个DataSet
        DataSet ds = new DataSet();
        protected void Page_Load(object sender, EventArgs e)
        {
            //用数据适配器的方式做一个查询
             con = new SqlConnection(conStr);
            string ssql = "select ID,username,PWD,loginname,qq,classname from Users";
            using(cmd = new SqlCommand(ssql, con))
            {
                //创建一个DataAdapter,传一个cmd
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                //应用数据适配器进行填充,填充到ds里
                da.Fill(ds);
                //指定一下数据源,.Tables[0]添加第一个table表
                //IdGridView.DataSource = ds;
                IdGridView.DataSource=ds.Tables[0];
                IdGridView.DataBind();
            }
        }
    }
}

③.DataAdapter调用存储过程[在数据库中加入存储过程调用]

 private string conStr = ConfigurationManager.ConnectionStrings["mySchool"].ToString();
        SqlConnection con = null;//相当于是电话
        SqlCommand cmd = null;//执行sql语句
        SqlDataReader dr = null;//用于储存查询结果
        //首先创建一个DataSet
        DataSet ds = new DataSet();
        protected void Page_Load(object sender, EventArgs e)
        {
            //用数据适配器的方式做一个查询
            con = new SqlConnection(conStr);
            //string ssql = "select ID,username,PWD,loginname,qq,classname from Users";
            //以上是之前的写法,这里我们直接传一个存储过程名
            using (cmd = new SqlCommand("procegDataAp", con))
            {
                //指定一个sqlcommand的CommandType(默认情况下等于CommandType.text)为CommandType的存储过程名
                cmd.CommandType = CommandType.StoredProcedure;
                List<SqlParameter> para = new List<SqlParameter>()
                {
                    //通过sqlParameter数组把它加到cmd里面去,需指定名称,类型,值
                    //模糊查询
                    new SqlParameter("@UserName","%"+TxtsUserName.Text.Trim()+"%")
                };
                foreach(var a in para)
                {
                    cmd.Parameters.Add(a);
                }
                //创建一个DataAdapter,传一个cmd
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                //应用数据适配器进行填充,填充到ds里
                da.Fill(ds);
                //指定一下数据源,.Tables[0]添加第一个table表
                //IdGridView.DataSource = ds;
                IdGridView.DataSource = ds.Tables[0];
                IdGridView.DataBind();
            }
        }

3.DataSet,DataTable,DataReader,DataAdapter的区别:

ⅰ.DtaSet是用来做sql连接的一种方法,意思是把数据库的副本存在应用程序里,相当于存在内存中的数据库,应用程序开始运行时,把数据库相关数据保存到DataSet.

ⅱ.DataTable表示内存中数据的一个表,常和DefaultView使用获取可能包括筛选视图或游标位置的表的自定义视图。

ⅲ.DataReader对象是用来读取数据库最简单的方式,它只能读取不能写入,而且是从头至尾往下读,无法只读某条数据,但它占用内存小,速度快.

ⅳ.DataAdapter对象是用来读取数据库,可读取写入数据,某条数据操作强,但它占用内存比DataReader大,速度慢,一般和DataSet连用

注.DataSet表示一个数据集,是数据在内存中的缓存。可以包含多个表DataTable,DataSet连接数据时是非面向连接的,把表全部读到sql中的缓存池,并断开于数据库的连接,DataReader连接数据库是面向连接的。读表时,只能向前读取,读完数据后友用户决定是否断开连接。

时间: 2024-08-24 10:49:03

Ado.net 三[SQL注入,DataAdapter,sqlParameter,DataSet]的相关文章

ADO.NET 防止SQL注入

规避SQL注入 如果不规避,在黑窗口里面输入内容时利用拼接语句可以对数据进行攻击 如:输入Code值 p001' union select * from Info where '1'='1 //这样可以查询到所有数据,不要轻易相信用户输入的内容 防止SQL注入攻击 通用方法:可以用正则匹配掉特殊符号 推荐方法:再给命令发送SQL语句的时候分两次发送  把SQL语句拆成两块 用户输入的是一块:本身写好的是一块 第一次把CommandText里写的sql语句发过去:第二次把变量值发过去,进行匹配  

三、ADO.Net基础【05】SQL注入漏洞(SQLInjection)

使用字符串拼接的方式把sql语句所需参数拼接到将要执行的sql语句中(参数一般只sql语句的过滤条件),对于用户的恶意输入可能导致不一的查询结果 例如:一个登录的例子(UserName和Password是用户的输入的用户名和密码). "select count(*)  from T_Users where UserName=' "+UserName+" ' and Password= ' "+Password+" ' "; C#这段代码指C#将要

浅谈ADO.NET中的对象——Connection、Command、DataReader、DataAdapter、DataSet、DataTable

可能是当初没有好好总结的缘故,学习.NET以来,对ADO.NET中的对象一直有些模糊,今天重新回顾了一下,通过查资料,总结,结合自己的观点整理一下ADO.NET中Connection.Command.DataReader.DataAdapter. DataSet.DataTable这几个对象的相关知识,希望对初学者能起到一个全局把控的作用,希望大牛能留下宝贵的指导意见. 以下的例子仅以连接 SQL Server数据库为例,所以分别以SqlConnection.SqlCommand.SqlData

防止sql注入的三种方法

常用的避免SQL注入的三种方法 一,存储过程 在学习数据库视频的时候接触过,它是存储在数据库中的一些事先编译好的指令.在用的时候不用重新编写,直接调用就好了.所以,使用它可以大大提高程序的执行效率. 那么,如果创建一个存储程序并使用它呢?这是我们今天要解决的问题 1.创建过程 可编程性--下拉菜单--存储过程--右键--查询菜单--指定模板参数的值--新建查询--输入语句--查询菜单中的分析检查语法是否正确--执行 2.具体创建语法 在创建存储程序时,为了应对各种变换的数据,通常会涉及到带参数的

SQL注入(三)

邮给我一个密码 我们意识到虽然不能添加一条新的记录在members表中,但我们可以通过修改一个存在的记录, 这也获得了我们的证明是可行的. 从先前的步骤中,我们知道[email protected]在系统中有一个帐号,我们使用SQL注入更新了他的数据库记录为我们的邮件地址: SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x'; UPDATE members SET email = '[email pro

(2)C#之ADO.Net 如何解决SQL注入漏洞攻击

SQL注入就是用户通过客户端请求GET或POST方式将SQL语句提交到服务端,欺骗服务器去执行恶意的SQL语句.例如下面这条SQL语句: 1 "select * from T_stuff where name = '"+txtbox1.text+"'"; 其中txtbox1是一个textbox控件,正常情况下我们会在这个textbox控件中输入一个姓名来查询员工的信息. 但是如果有用户在这个textbox控件中恶意输入一个拼接字符串,例如:"1' or '

web实验三——pikachu之sql注入

(一)数字型注入 首先更改1项的值构造payload找到注入点,之后构造payload注出其他信息 查表名 查字段名 最终输入payload: value="1 union select concat(id,'|',username,'|',password,'|',level),2 from users" 结果 (二)字符型注入 使用单引号跳出字符串,最后使用#注释掉多余sql语句,跳过前面查表名字段名的步骤,直接给出最后payload: ' union select id,conc

DVWA(三):SQL injection 全等级SQL注入

(本文不定期更新) 一.所需环境: 1.DVWA 2.web环境 phpstudy/wamp 3.burp suite 二.SQL注入产生的原因: 程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患 用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据或进行数据库操作. 三.关于SQL注入需要注意的几个点: 1.SQL注入的攻击流程: (1)判断注入点:一般分为三大类 GET.POST参数触发SQL注入,Cookie触发注入 (2)判断注入类

php连接mysql的三种方式和预处理下的sql注入

0x00 前言 学习了一下堆叠注入和这三种连接方式预处理下的SQL注入问题. 0x01 基础知识 参考: https://www.cnblogs.com/joshua317/articles/5989781.html https://www.cnblogs.com/geaozhang/p/9891338.html 1.即时 SQL 一条 SQL 在 DB 接收到最终执行完毕返回,大致的过程如下: 1. 词法和语义解析: 2. 优化 SQL 语句,制定执行计划: 3. 执行并返回结果: 如上,一条