zoukankan      html  css  js  c++  java
  • 使用参数化查询防止SQL注入漏洞

    SQL注入漏洞曾经是Web应用程序的噩梦,CMS、BBS、Blog无一不曾受其害。

    SQL注入的原理
    以往在Web应用程序访问数据库时一般是采取拼接字符串的形式,比如登录的时候就是根据用户名和密码去查询:

    string sql = "SELECT TOP 1 * FROM [User] WHERE UserName = ‘” + userName + “‘ AND Password = ‘” + password + “‘”;

    其中userName和password两个变量的值是由用户输入的。在userName和password都合法的情况下,这自然没有问题,但是 用户输入是不可信的,一些恶意用户只要用一些技巧,就可以绕过用户名、密码登录。

    假设password的值是”1′ or ‘1′ = ‘1“,userName的值随便取,比如是”abc”,那变量sql的 值就是:


    "SELECT TOP 1 * FROM [User] WHERE UserName = ‘abc’ AND Password = ‘1′ or ‘1′ = ‘1′”

    由于’1′ = ‘1′恒为真,因此只要User表中有数据,不管UserName、Password的值是否匹配,这条SQL命令准能查出记录来。就这样,登录系统就被 破解了。

    以往的防御方式
    以前对付这种漏洞的方式主要有三种:

    字符串检测:限定内容只能由英文、数字等常规字符,如果检查到用户输入有特殊字符,直接拒绝。但缺点是,系统 中不可避免地会有些内容包含特殊字符,这时候总不能拒绝入库。
    字符串替换:把危险字符替换成其他字符,缺点是危险字符可能有很多,一一枚举替换相当麻烦,也可能有漏网之 鱼。
    存储过程:把参数传到存储过程进行处理,但并不是所有数据库都支持存储过程。如果存储过程中执行的命令也是通 过拼接字符串出来的,还是会有漏洞。
    参数化查询
    近年来,自从参数化查询出现后,SQL注入漏洞已成明日黄花。

    参数化查询(Parameterized Query 或 Parameterized Statement)是访问数据库时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值。

    在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部份来处理,而是在数据库完成SQL指令的编译后,才 套用参数运行,因此就算参数中含有指令,也不会被数据库运行。Access、SQL Server、MySQL、SQLite等常用数据库都支持参数化查询。

    在ASP程序中使用参数化查询
    ASP环境下的参数化查询主要由Connection对象和Command对象完 成。

    Access数据库只支持匿名参数,在传入参数的位置用问号代替即可。SQL Server数据库虽然支持匿名和非匿名的参数,但是在ASP中也仅能使用匿名参数。

    var conn = Server.CreateObject("ADODB.Connection");
    conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("Test.mdb");
    conn.Open();

    var cmd = Server.CreateObject(“ADODB.Command”);
    cmd.ActiveConnection = conn;
    cmd.CommandType = 1;
    cmd.CommandText = “SELECT TOP 1 * FROM [User] WHERE UserName = ? AND Password = ?“;
    cmd.Parameters.Append(cmd.CreateParameter(”@UserName”, 200, 1, 20, “user01″));
    cmd.Parameters.Append(cmd.CreateParameter(”@Password”, 200, 1, 16, “123456″));

    var rs = cmd.Execute();
    Response.Write(rs(”UserId”).value);

    rs.Close();
    conn.Close();

    在ASP.NET程序中使用参数化查询
    ASP.NET环境下的查询化查询也是通过Connection对象和Command对象完成。如果数据库是SQL Server,就可以用有名字的参数了,格式是“@”字符加上参数名。

    SqlConnection conn = new SqlConnection("server=(local)\\SQL2005;user id=sa;pwd=12345;initial catalog=TestDb");
    conn.Open();

    SqlCommand cmd = new SqlCommand(“SELECT TOP 1 * FROM [User] WHERE UserName = @UserName AND Password = @Password“);
    cmd.Connection = conn;
    cmd.Parameters.AddWithValue(”UserName”, “user01″);
    cmd.Parameters.AddWithValue(”Password”, “123456″);

    SqlDataReader reader = cmd.ExecuteReader();
    reader.Read();
    int userId = reader.GetInt32(0);

    reader.Close();
    conn.Close();

    MySQL的参数格式与SQL Server有点区别,是以“?”加上参数名。

    MySqlConnection conn = new MySqlConnection("server=127.0.0.1;uid=root;pwd=12345;database=test;");
    conn.Open();

    MySqlCommand cmd = new MySqlCommand(“SELECT * FROM `User` WHERE UserName = ?UserName AND Password = ?Password LIMIT 1″);
    cmd.Connection = conn;
    cmd.Parameters.AddWithValue(”UserName”, “user01″);
    cmd.Parameters.AddWithValue(”Password”, “123456″);

    MySqlDataReader reader = cmd.ExecuteReader();
    reader.Read();
    int userId = reader.GetInt32(0);

    reader.Close();
    conn.Close();

    本篇文章来源于 站长资讯网 原文链接:http://www.chinahtml.com/1006/asp-127561481718846.html

  • 相关阅读:
    vue 优化hash持久化缓存
    用vue的抽象组件来做一个防止img标签url为空或url地址出错的验证
    读源码学会一些编程小技巧
    webpack编译后的代码如何在浏览器执行
    vue@cli3 public目录下的静态图片,如何使用在css类文件中(sass可行,纯css不行)
    vue@cli3 项目模板怎么使用public目录下的静态文件,找了好久都不对,郁闷!
    vscode如何配置ts的lint,如何配置才能让eslint和prettier不冲突一键格式化代码(vue开发使用)
    rollup 使用babel7版本的插件rollup-plugin-babel,rollup-plugin-babel使用报错解决办法。
    深入研究webpack之Tree Shaking相关属性sideEffects用处
    前端性能优化之http缓存
  • 原文地址:https://www.cnblogs.com/java20130723/p/3211631.html
Copyright © 2011-2022 走看看