B/S模式下演示SQL注入安全性问题

什么是SQL注入,简单的说就是我只需要知道任意一个用户名而不需要知道密码就可以登录进系统,一般都发生在登录界面

1.SqlServer数据库的设计

CREATE TABLE userTable
(
id int identity(1,1) primary key,
username varchar(20),
password varchar(20)
)
insert into userTable(username,password) values('zhangsan','123456')
insert into userTable(username,password) values('lisi','654321')

2.前端设计
为了方便演示,密码框也是文本输入样式

<form id="form1" runat="server">
    用户名:<input type="text" name="username"/><br />
    密&nbsp;&nbsp;&nbsp;码:<input type="text" name="password"/><br />
    <input type="submit" value="提交"/>
</form>

3.后台设计
后台只有在拼接SQL参数的时候才有可能发生SQL注入,所以后台会分2种情况演示:一种是拼接式sql,另一种是参数化查询sql。还有一点就是SQL注入的情况不仅仅发生在后台语言向数据库发起sql命令的时候,sqlServer中也是可以完成sql注入的,后面会演示

SqlConnection sqlConnection;
protected void Page_Load(object sender, EventArgs e)
{
    if(IsPostBack)
    {
        String username = Request["username"];
        String password = Request["password"];
        if(sqlConnection==null)
            sqlConnection = new SqlConnection("Server=.;user=sa;password=guobeizxc;database=lawnet");
        //这里使用拼接的方式编写sql
        String sql = "SELECT * FROM userTable WHERE username='" + username + "' AND password='" + password+"'";
        SqlCommand sqlCommand = new SqlCommand(sql, sqlConnection);
        sqlCommand.CommandType = System.Data.CommandType.Text;
        DataSet ds = new DataSet();
        SqlDataAdapter sda = new SqlDataAdapter(sqlCommand);
        sda.Fill(ds);
        //如果这个dataset里面有行,说明数据库返回了数据,即表示登录成功
        if(ds.Tables[0].Rows.Count>0)
        {
            Response.Write("<script type='text/javascript'>alert('登录成功')</script>");
        }
        else
        {
            Response.Write("<script type='text/javascript'>alert('登录失败')</script>");
        }
    }
}

演示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以在后台使用拼接式sql很容易导致这种问题发生,目前主流的形势都是用的参数化查询,后台可以修改一下

SqlConnection sqlConnection;
protected void Page_Load(object sender, EventArgs e)
{
    if(IsPostBack)
    {
        String username = Request["username"];
        String password = Request["password"];
        if(sqlConnection==null)
            sqlConnection = new SqlConnection("Server=.;user=sa;password=guobeizxc;database=lawnet");
        //这里使用拼接的方式编写sql
        //String sql = "SELECT * FROM userTable WHERE username='" + username + "' AND password='" + password+"'";
        //使用参数化查询
        String sql = "SELECT * FROM userTable WHERE username=@username AND password=@password";
        SqlCommand sqlCommand = new SqlCommand(sql, sqlConnection);
        sqlCommand.CommandType = System.Data.CommandType.Text;
        SqlParameter[] sqlParameters = { new SqlParameter("@username", username), new SqlParameter("@password", password) };
        sqlCommand.Parameters.AddRange(sqlParameters);
        DataSet ds = new DataSet();
        SqlDataAdapter sda = new SqlDataAdapter(sqlCommand);
        sda.Fill(ds);
        //如果这个dataset里面有行,说明数据库返回了数据,即表示登录成功
        if(ds.Tables[0].Rows.Count>0)
        {
            Response.Write("<script type='text/javascript'>alert('登录成功')</script>");
        }
        else
        {
            Response.Write("<script type='text/javascript'>alert('登录失败')</script>");
        }
    }
}

测试

在这里插入图片描述
这样就避免了SQL注入的风险,现在在数据库中演示,先看一下最终的sql长什么样子

declare @userid varchar(20),
		@password varchar(20),
		@sql nvarchar(max)
set @userid='''zhangsan'' or 1=1 --'
set @password='123456789'
set @sql='select * from userTable where username='+@userid +'and password='''+@password+''''
print @sql

在这里插入图片描述

看上去应该可以注入成功,现在使用sp_executesql执行一下看看

exec sp_executesql @sql

在这里插入图片描述
可以看出这是注入成功了,其实使用sp_executesql相当于在后台动态拼sql一样,sql查询编辑器会完完整整的执行,再换一种方式执行,下面这种方式相当于参数化查询sql,是可以避免注入的

declare @userid varchar(20),
		@password varchar(20),
		@sql nvarchar(max)
set @userid='''zhangsan'' or 1=1 --'
set @password='123456789'
select * from userTable where username=@userid and password=@password

在这里插入图片描述
sql注入的基本演示就是这些,读者也别浪费时间去各个网站去尝试,反正我是不太相信可以注入成功的。虽然现在的软件工程师水平良莠不齐,但现在基本上都是使用框架开发,一些基本的安全性问题框架都早就已经做好了,不太可能会出现这种低级错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值