一.安全测试原则与常见的安全威胁:
1.安全需求:
※认证:对认证的用户的请求返回
※访问控制:对未认证的用户的权限控制和数据保护
※完整性:用户必须准确的收到服务器发送的信息
※机密性:信息必须准确的传递给预期的用户
※可靠性:失败的频率是多少?网络从失败中恢复需要多长时间?采取什么措施来应对灾难性的失败?(个人理解这个地方应该更偏向于容错容灾测试的范畴)
※不可抵赖:用户应该能证明接收到的数据来自特定的服务器
2.常见的安全测试内容
权限控制
SQL注入
URL安全测试
XSS(跨站脚本攻击)
CSRF(跨站请求伪造)
URL跳转漏洞
其他安全方面的考量
接下来,我们以一个C#实现的下常见的MVC架构网站为例,来分析具体的各个安全测试角度。
二.权限控制
权限控制相对来说比较简单,功能测试的过程中也接触过不少,主要就是考虑以下方面:
1.用户权限:我们假设存在两个用户A,B;其中A的权限级别很高,B的权限级别则很低:
只有A能进行的操作,B能不能进行操作;
只有A能看到的页面,B能不能看到;
2.页面权限:
必须登录才能看到的页面,不登录直接访问能否看到?
必须A-B-C的页面,能否直接A-C?
通常来说单纯的权限控制页面测试不复杂,但是因为权限控制和后续的URL跳转、Session等方面结合的比较紧密,所以单独提出来。
三.SQL注入
1.SQL注入原理
以Sql Sever为例,C#提供了两种操作数据库的方法,以实现Sql Sever的查询功能为例(Mysql只需要将Sql对象替换为MySql对象即可):
A.直接使用传入的Sql进行数据库操作:
public static DataSet QuerySql(string sSql)
{
DataSet ds = new DataSet();
try
{
Open();
SqlDataAdapter mDataAdpter = new SqlDataAdapter(sSql, conn);
mDataAdpter.Fill(ds);
}
catch (SqlException ex)
{
throw new Exception(ex.Message);
DataBaseException = ex.Message;
}
finally
{
conn.Close();
}
return ds;
}
B.使用SqlParameter对象,对参数进行格式化,分离控制语句与执行语句:
public static DataSet QuerySql(string sSql, SqlParameter[] Params)
{
DataSet ds = new DataSet();
SqlCommand comm = new SqlCommand();
try
{
Open();
comm.Connection = conn;
comm.CommandType = CommandType.Text;
comm.CommandText = sSql;
comm.Parameters.Clear();
foreach (SqlParameter p in Params)
{
comm.Parameters.Add(p);
}
SqlDataAdapter mAdapter = new SqlDataAdapter(comm);
mAdapter.Fill(ds);
}
catch (SqlException ex)
{
DataBaseException = ex.Message;
throw new Exception(ex.Message);
}
return ds;
}
接下来我们来看以下场景:
用户登录,账号密码存在User表中,该表字段为ID,Name,PassWord三个字段,验证用户登录时直接传用户输入的用户名与密码给数据库,如果我们直接采用方式一,那么代码实现如下:
//获取传入的用户UserName与PassWord
string sql = "SELECT * FROM User WHERE UserName = '"+UserName+"' AND PassWord = '"+PassWord+"'";
//其他处理代码
假设我们的账户名称是admin,密码是123,那么构造出的sql就是:
SELECT * FROM User WHERE UserName = ’admin’ AND PassWord = ’123’
执行结果看起来没有问题,但是如果这个时候我们输入的密码是 ‘’or 1=1时,那么实际执行的SQL就变成了:
SELECT * FROM User WHERE UserName = ’admin’ AND PassWord = '''' OR 1=1
(这里输入两个分号是因为构造sql的时候就已经是分号了,在sql sever中查询的字符串中带有分号则是需要再加一个分号进行转义)
由于1=1恒等式的存在,这条sql会直接查询出整个表的数据;就算没有相关权限,服务器也会认为是一个有效用户进行处理。
如果我们再进一步,输入密码‘’or 1=1;drop table User
那么结果会是什么样呢?User这个表会直接被删除掉!这个时候网站就会因为User表不存在而报错,产生严重的异常。
综上所述,SQL注入的原理就是通过构造符合SQL语法的参数传入程序,通过执行SQL语句进而执行攻击的操作;原因是程序完全信任了传入的数据,致使非法数据能够入侵系统。
2.解决方案:
在了解了SQL注入原理后,我们可以做出针对性的一些措施,如:
尽量避免使用动态构造SQL,而是使用SqlParameter对参数进行格式化或使用框架提供的一些功能,分离控制语句与执行语句;
对传入的字符进行转义处理,’和%、_、[]等通配符进行转义处理,保证执行SQL的时候这些字符是正确在字符串内进行处理的;
在前端表单或控件中增加验证,保证传入后台的数据是合法的;
数据库权限控制,只给对应功能需要的权限,比如登录页面只能进行查询,不赋予其执drop、update、delete、truncate等操作的权限。