对SQL注入的一点思考

来源:互联网 发布:小蝌蚪旅游定制 知乎 编辑:程序博客网 时间:2024/05/01 00:25

ASP网页的一大安全问题是SQL注入问题。之所以SQL语句能被注入,是因为输入的参数有可能会被当作代码的一部分而被执行,即被当作“元语言”处理。在ASP中,我们一般这样构造SQL语句:sql="select * from table where id='" & id & "'",我们期望输入的id参数被当作“目标语言”,然而,给id一个特殊的串值,它依然可能被当作代码执行。id周围加了“'”,使得“?id=1 and 1=1”不好使了,然而id里面完全也可以包含“'”来绕过这道“防线”,比如“?id=1' and '1'='1”。

一种简单的解决办法就就是在参数周围加“'”并用以下这段代码对参数处理一下:

Function SafeRequest(ParaName,ParaType)
  'ParaName:参数名称-字符型
  'ParaType:参数类型-数字型(1表示以上参数是数字,0表示以上参数为字符)
  Dim ParaValue
  ParaValue=Request(ParaName)
  If ParaType=1 then
    If not isNumeric(ParaValue) then
      Response.write "参数" & ParaName & "必须为数字型!"
      Response.end
    End if
  Else
    ParaValue=replace(ParaValue,"'","''")
  End if
  SafeRequest=ParaValue
End function

可以看出,这段代码就是把“'”换成了“目标语言”的表示形式(当然还有判断应该是数字的参数的实际值是否为数字的功能)。

回忆DOS窗口编程的时代,输入的是变量的值,用来被程序处理,顶多用来作为控制信息。所以不会被“注入”(当然,那个时代也有那个时代有攻击方式,比如说缓冲区溢出)。

想起HDLC协议,字节“01111110”是一个帧的开始标志和结束标志,也即“元语言”,若数据中出现“01111110”,则必须将其替换掉防止系统把它当作“元语言”处理,方法为若遇到连续5个“1”,则在后面自动加一个“0”,也即“0”比特插入法。

对JSP,JDBC中的PreparedStatement先构造一个带一串“问号”的SQL语句,然后再将“问号”处填入,系统通过替换手段严格将填入的东西当作目标语言处理,因此可以防止SQL注入。

对于设计一种“语言”(不一定是编程语言啦,可以是用户与系统交互的语言、通信协议语言、分层结构软件层与层之间交互的语言等等)来讲,把“元语言”跟“目标语言”搞清楚还是很有必要的。

原创粉丝点击