SQL注入攻击

网站登录场景:用户输入账号、密码提交到服务端校验。
示例正常输入:

  • 账号:admin
  • 密码:123456

程序员直接拼接字符串生成SQL语句:

select * from user where name = 'admin' and password = '123456'Code language: JavaScript (javascript)

数据库查询到记录,则登录成功;查无记录则拒绝登录。

SQL注入攻击演示

黑客在密码输入框恶意输入:

123456' or '1'='1Code language: JavaScript (javascript)

程序直接拼接后最终执行SQL:

select * from user where name = 'admin' and password = '123456' or '1'='1'Code language: JavaScript (javascript)

'1'='1' 条件恒成立,整条SQL查询永远返回数据,黑客不需要正确密码即可登录系统。

直接把用户输入当做SQL代码拼接,用户可以篡改SQL语义。

解决方案:参数化查询

不要拼接用户输入,使用 ADO.NET SqlParameter 参数化查询,用户输入只会被当做普通字符串值,不会被解析成SQL指令。

C#示例代码:

StringBuilder strSql = new StringBuilder();
strSql.Append("select * from user where name = @name and password = @pwd");

SqlParameter[] parameters = {
    new SqlParameter("@name", SqlDbType.Nvarchar,50),
    new SqlParameter("@pwd", SqlDbType.Nvarchar,50)
};
parameters[0].Value = name;
parameters[1].Value = pwd;

return DbHelperSQL.Exists(strSql.ToString(), parameters);Code language: JavaScript (javascript)

注意

  1. SQL语句里参数不要加单引号@name,不能写成 '@name'
  2. 用户输入全部赋值给SqlParameter对象,禁止直接拼接进SQL字符串
  3. 底层数据库驱动会自动处理特殊符号,彻底抵御SQL注入。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注