这是发表在原公司(已经在股东们个人利益斗争中轰然倒塌)内部BBS上的一篇贴子,随便贴上来,(为保护在用系统及其它有部分删节及修改),适合初学者!
http://www.safechina.net (转载请注明出处)
-----------------------------------------------------------
浅谈B/S系统安全
随着这些年的发展B/S系统已经超出了个人主页,留言本之类的应用,各种公司的核心应用都逐渐构建在WEB上了,而WEB服务器端的程序安全也倍受瞩目,本文先通过几个实例引入一些常见的安全问题,然后讨论一下WEB应用代码编写的一些基本准则和建议。由于本人已很长时间不从事这方面的工作了,所讲的内容可能有些过时或不对的地方,各位看官就权当笑话。
如果不想看冗长无味的论述,就直接翻到:“一些编程原则”部分。
一. SQL注入(SQL Injection)
这是现在出现的最多也最易应用的一个问题,使用数据库的系统就有可能出现这种问题,成因是对用户的输入没有做必要的检测及过滤,导致用户执行非法SQL语句。常见的如登陆程序,使用1’or ‘1’=’1进行任意用户登陆,记得98年台湾李登X的网站就是因此被黑….呵呵,好些年了,不过问题依然。 对于这类问题的网上已经有无数的实例和教学,本来不想趟这混水,不过正是由于其普遍性(我见过至少5个厂商10个以上的电信行业中的各种web系统存在不同程度上的登陆问题)和埋在其深处的语义方面的内容,所以决定从2003年底某系统的代码分析记录谈起。
例一:
以下内容来自2003年底的代码分析记录,代码文件的最后修改日期为2003.12.XX
XX帐务--XX管理系统
等级:AAA 严重
情景:登陆
条件 已经某合法用户名(非必要条件),如:tt。
过程:登陆界面中输入
操作员:1’or ‘1’=’1
口令:随便
执行结果:登陆成功,拥有所有操作权限。
问题分析
login_check.jsp
line 15处开始:
此处没进行用户输入有效性处理………
user_code = request.getParameter("user_code").trim();
strSql = "select count(*) from UserInfo where user_code = ‘"+ user_code +"‘ and password = ‘" +password+ "‘ and status=1";
以上查询为问题出处,当user_code为tt’ or 1=1 时strSql 为:
where user_code=’tt’ OR 1=1 and password=’aaa’ and status=1
结果为表中所有记录…..,通过对user_code输入值的构造几乎可以对数据库进行任何操作,部分数据库系统中可能获取系统最高权限……….
上面描述的是SQL Injection问题,进一步的转为应用逻辑完整性判断的讨论,用户登陆需要强壮的判断逻辑,仅判断是否返回结果是不够的,还应该加上查询结果的字段的内容是否与对应的输入一致,这样即使查询结果返回多条记录也不会登陆成功,上例中执行完述查询后因为不严谨的判断,不但导致用户登陆成功,而且还拥有系统的所有操作权限:
if (count.equals("0")){
登陆失败,错误处理。
}else{
strSql = "select 字段名 from UserInfo where user_code = ‘"+ user_code +"‘";
以上语句由于user_code中有一or条件,所以取得系统的所有操作权限…….