永远不要相信用户的输入
2014-11-22 17:30
417 查看
“永远不要相信用户的输入”是对设计人员和编码人员说的,是进行安全设计和安全编码的重要准则。换句话说,任何输入数据在证明其无害之前,都是有害的。许多危险的漏洞就是因为过于相信用户的输入是善意的而导致的。 文章“我的网络安全观点之六:漏洞无处不在”中的例子中,程序直接引用输入数据作为页面模板文件名装载并显示处理,这是一个典型的信息泄漏的漏洞。还有一种常见的漏洞是直接引用输入数据构造查询数据库的SQL语句,下面举一个例子(稍有黑客常识的人都应该熟悉这个例子): 以下是一段验证用户密码的程序: =========================================================================== ... q.SQL.Clear; q.SQL.Add('SELECT COUNT(*) FROM EMP ' + ' WHERE CODE = ''' + Request.ContentFields.Values['UserCode'] + '''' + ' AND PASSWORD = ''' + Request.ContentFields.Values['Password'] + ''''); q.Open; if q.Fields[0].AsInteger > 0 then //合法用户 else //非法用户; q.Close; ... =========================================================================== 攻击者不需要知道合法用户的密码就能直接进入系统,攻击方法是在登录页面的用户名输入框中随便输入一个字符串例如aaa,在密码输入框中输入 1' or '1'='1 按照此输入,程序中的SQL语句变为 SELECT COUNT(*) FROM EMP WHERE CODE = 'aaa' AND PASSWORD = '1' or '1'='1' 查询条件变成了恒等式,于是通过了验证。造成这个漏洞的原因在于程序对输入数据未作处理直接将其用于SQL语句。如果程序中某个UPDATE语句或DELETE语句存在类似漏洞,则有可能造成数据丢失。为修补以上漏洞,应该对用户输入数据进行规范性检查和过滤。然后以如下方式进行验证: =========================================================================== ... sUserCode := 对Request.ContentFields.Values['UserCode']进行规范后的结果; sPassword := 对Request.ContentFields.Values['Password']进行规范后的结果; q.SQL.Clear; q.SQL.Add('SELECT PASSWORD FROM EMP ' + ' WHERE CODE = ' + QuotedStr(sUserCode)); q.Open; if q.FieldByName('PASSWORD') = sPassword then //合法用户 else //非法用户; q.Close; ... =========================================================================== 以上程序中,QuotedStr实际上也是对数据的一种规范处理。 (注:我会制订关于用户输入数据检查和处理的规范,加进我们的详细设计规范和编码规范) 如果我们能对所有用户输入进行详细的检查,那么软件中的漏洞就会大大减少。因为无论是什么样的漏洞,攻击者要利用此漏洞实施攻击,总要向系统输入一些数据才能实施攻击,堵住了非法和恶意的输入,就堵住了很多类型的攻击。 对于WEB程序开发人员来说,“永远不要相信用户的输入”这条准则可以引申为“永远不要相信客户端信息”,客户端信息包括请求的URL、cookie、提交的表单等,总之TWebRequest的所有属性都不要相信。例如,有的设计者期望通使用客户端的JavaScript脚本进行输入数据检查,在服务端就省略了检查,这种做法是错误的。因为JavaScript可能被浏览器禁用,或者被客户端防火墙禁用,或者某种特殊的浏览器忽略了你的JavaScript,这些都会使客户端JavaScript失效或部分失效。正确的做法是在客户端和服务端都作相同的检查,客户端的检查的目的是为了界面的友好、节省用户的时间,服务端的检查才是为了数据的完整和安全。 有些开发人员会说对输入数据进行如此多的检查会影响性能,实际上,大多数输入检查并不对性能造成大的损害,即使有损害,一个稍慢但是相对安全的系统也比一个快速但容易受到攻击的系统要好。如果客户对你的系统性能不满意,应寻找其它途径提高性能,不要通过减少安全检查来提高性能,因为当客户的系统因为漏洞被攻破以后,你面临的就不是几句抱怨,而是一场灾难了。 对待用户输入,实际上也是一个转变观念的问题,就像我在“我的网络安全观点之五:敌人无处不在”中描述的,周围的世界不可思议的充满了敌意,我们必须怀疑一切,以前那种充满善意和无知的程序运行环境一去不复返了,取而代之的是恶意和数不清的黑客工具。 |
相关文章推荐
- web开发安全守则之永远不要相信用户的输入
- 永远不要相信用户输入的!
- 【安全设计准则】永远不要相信客户端的输入
- HTTP安全随想,第一指导原则:不要相信任何用户的输入[]
- PHP 不要相信用户的任何输入
- 永远不要相信自己
- 做技术注意,操作一个步骤,永远不要相信以前的经验,因为你面临的环境可能已经发生变化,但是没有人告诉你.
- 管理故事216之017-不相信自己的意志,永远也做不成将军--证创新者的“不要太相信别人”
- 不要相信自己,永远做到最谨慎1(笔记)
- 不要相信权威 永远相信自己的判断
- 做技术注意,操作一个步骤,永远不要相信以前的经验,因为你面临的环境可能已经发生变化,但是没有人告诉你.
- c++讨论会 永远不要相信那些自称懂C++的程序员 (Never trust a programmer who says h
- 保险箱Pro、加密相册Pro、私密相册app如下图标的用户请不要升级到iOS11,升级到iOS11会导致这些app永远进不去
- 不要轻易相信用户
- 不要相信客户端的输入
- 实现一个"可变二维数组",这个二维数组的行数要求用户从键盘输入,每行的元素个数仍由用户从键盘输入. //数组元素值用户可以自定义.最后把二维数组打印出来.不要忘记释放数组内存. /*void main
- 防止SQL注入:永远不要信任外界输入的数据,特别是来自于客户端的,包括选择框、表单隐藏域和 cookie
- 不要相信短信:iOS漏洞允许用户发送虚假短信
- 致创业者:不要听用户瞎BB 他们身体永远比嘴巴老实
- 不要相信表象