• SQL语法用like %或in时Parameters要怎么用才能避免SQL Injection的问题


    原文地址:http://tw.myblog.yahoo.com/jeff-yeh/article?mid=603&prev=605&next=597

    本来是繁体,让我转成简体了,如下

    很多人应该都经历过一段T-SQL的学习成长路程,最多人最常用的就是直接把使用者输入的值,直接组到查询字符串里.

    例如 :

    string strCmd="select * from testdb where testid ='"+TextBox1.Text.Trim()+";"; 

    很多范例及书籍都有这样的写法,可是这写法有很严重的SQL Injection的问题,这也不是个新问题,这是很久以前就有发现的,有些人还以为Hot Fix或Service Pack可以修正SQL Injection的问题,但这是程序写法的问题,跟Hot Fix或Service Pack没有关系.

    记得过去有位同事,有多年的程序撰写经验,后来跟我一起Work了一段时间,他的写法也是如此,当时提出这个安全问题时,还不被重视,但小弟手就是贱,为了让上头重视这个问题,只好自己动手去"注射"了,我没做什么,就很单纯的关掉DB而已,后来上头才发现这个问题的严重性,才要求更改.

    后来陆续对安全性的重视提高了,开始想着要怎么去解决这个问题,就延伸出第二种写法,开始去过滤关键词,置换等消极的方式,有时还会发现新的问题,所以就一直修不停.

    例如 :

    string strCmd="select * from testdb where testid ='"+TextBox1.Text.Trim().Replace("'","%")+";";

    这只是示意性的换掉单引号,但还有很多关键词或符号.

    后来决定要想办法把使用者的查询值放到Parameters的方式去处理,而做法也没想象中的难.

    以like的问题来说:

    SqlCommand cmd=new SqlComand(); //其它怎么用Connection等,因为不是重点,所以带过不写

    cmd.Parameters.Add("@testid",TextBox1.Text.Trim());

    cmd.CommandText="select * from testdb where testid like @testid+'%'";

    这样就能做到 like TextBox1.Text.Trim()% 的效果,而且不用担心使用者输入的字有什么关键词在里面.

    那么in要怎么做?

    会用in的时候,一定是有很多查询的值要查,所以做法有很多种,但意思差不多.

    例如我的查询条件有"Jeff","Jack","Jay","Jason",将这些条件个个分开放到一个String Arrary里.

    SqlCommand cmd=new SqlComand(); //其它怎么用Connection等,因为不是重点,所以带过不写

    cmd.CommandText="select * from testdb where testid in (";

    string strName="Jeff,Jack,Jay,Jason";//要用in查询的数据

    string[] strQry=strName.Split(",".ToCharArray());//把它切到String Array里去

    int intCount=0;

    foreach (string sq in strQry)

    {

    cmd.Parameters.Add("@TestID"+intCount, sq) //所以每次的变量都会不同

    cmd.CommandText+="@TestID"+intCount+",";

    intCount++;//变数加1

    }

    cmd.CommandText=cmd.CommandText.Remove(cmd.CommandText.Length-1,1)+")"; //把最后一个逗号换为右括号.

    最后就会组出select * from testdb where testid in (@TestID0,@TestID1,@TestID2,@TestID3)

    未来会不会有第四种改进写法,就不知道了,看各位有没有什么好看法,或是未来会不会我又有遇到什么问题可以动动脑.

    #2008/9/13 补充

    在网友提供的信息,发现用Parameters,在用Like时,使用者输入的%也是当通配符在使用.例如:

    cmd.Parameters.Add("@testid","Jeff%");

    cmd.CommandText="select * from testdb where testid like @testid";

    查询结果会将所有的Jeff开头的数据取回,而底线 _ 的单一字的通配符也是有同样的效果,那这样用户真的想要找数据内有%或是_时的数据时,要怎么辨才能达成?目前是想到一个方法,但要用到escape这个方式.

    例如 :

    cmd.Parameters.Add("@testid","Jeff%".Relpace("!","!!").Relpace("%","!%").Relpace("_","!_")+"%");

    cmd.CommandText="select * from testdb where testid like @testid escape '!'";

    前三个Relpace的动作,是把使用者输入的! (因为escape 符号是用!),%及_都在前面加个!,让它被视为原意做为查询条件,最后加上的%,因为没前面先加!,所以最后一个%仍为通配符使用,所以举例数据库的数据如下:

    Jeff1

    Jeff%1

    Jeff%2

    Jeff%_1

    Jeff2

    查询结果会是 :

    Jeff%1

    Jeff%2

    Jeff%_1

    这是目前想到的做法~

  • 相关阅读:
    WinForm RadioButton 默认不选中
    使用Devexpress时,ArcEngine 加载地图空白。
    正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。
    Vue使用iframe加载本地html,并进行通信,传递参数
    找不到 Microsoft.VisualStudio.Shell.Interop.IVsReferenceManager 服务的实例
    计算经纬度两点间距离
    The system clock has been set back more than 24 hours
    nmcli命令行修改网络连接名称
    linux安装mysql5.7
    <<<物品借记登记>>>
  • 原文地址:https://www.cnblogs.com/sdqxcxh/p/1798991.html
Copyright © 2020-2023  润新知