您的位置:首页 > 其它

永远不要相信用户的输入

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失效或部分失效。正确的做法是在客户端和服务端都作相同的检查,客户端的检查的目的是为了界面的友好、节省用户的时间,服务端的检查才是为了数据的完整和安全。

    有些开发人员会说对输入数据进行如此多的检查会影响性能,实际上,大多数输入检查并不对性能造成大的损害,即使有损害,一个稍慢但是相对安全的系统也比一个快速但容易受到攻击的系统要好。如果客户对你的系统性能不满意,应寻找其它途径提高性能,不要通过减少安全检查来提高性能,因为当客户的系统因为漏洞被攻破以后,你面临的就不是几句抱怨,而是一场灾难了。

    对待用户输入,实际上也是一个转变观念的问题,就像我在“我的网络安全观点之五:敌人无处不在”中描述的,周围的世界不可思议的充满了敌意,我们必须怀疑一切,以前那种充满善意和无知的程序运行环境一去不复返了,取而代之的是恶意和数不清的黑客工具。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐