安全测试基础

发布时间:2024-07-10 14:01

安全测试基础

 

一般来说,版本功能测试完成,对应的用例也实现了自动化,性能、兼容、稳定性测试也完成了以后,我们就需要考虑到系统的安全问题,特别是涉及到交易、支付、用户账户信息的模块,安全漏洞会带来极高的风险。

 

一.安全测试原则与常见的安全威胁:

1.安全需求:

※认证:对认证的用户的请求返回

※访问控制:对未认证的用户的权限控制和数据保护

※完整性:用户必须准确的收到服务器发送的信息

※机密性:信息必须准确的传递给预期的用户

※可靠性:失败的频率是多少?网络从失败中恢复需要多长时间?采取什么措施来应对灾难性的失败?(个人理解这个地方应该更偏向于容错容灾测试的范畴)

※不可抵赖:用户应该能证明接收到的数据来自特定的服务器

2.常见的安全威胁:

\"安全测试基础_第1张图片\"

3.常见的安全测试内容:

权限控制

SQL注入

URL安全测试

XSS(跨站脚本攻击)

CSRF(跨站请求伪造)

URL跳转漏洞

Session与Cookie测试

其他安全测试

 

接下来,我们以一个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进行数据库操作:

  publicstaticDataSet QuerySql(string sSql)

        {

            DataSet ds = newDataSet();

            try

            {

               Open();

                SqlDataAdapter mDataAdpter = newSqlDataAdapter(sSql, conn);

               mDataAdpter.Fill(ds);

            }

            catch (SqlException ex)

            {

                thrownewException(ex.Message);

               DataBaseException = ex.Message;

            }

            finally

            {

               conn.Close();

            }

            return ds;

        }

 B.使用SqlParameter对象,对参数进行格式化,分离控制语句与执行语句:

  

 publicstaticDataSet QuerySql(string sSql, SqlParameter[] Params)

        {

            DataSet ds = newDataSet();

            SqlCommand comm = newSqlCommand();

            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 = newSqlDataAdapter(comm);

               mAdapter.Fill(ds);

            }

 

            catch (SqlException ex)

            {

               DataBaseException = ex.Message;

                thrownewException(ex.Message);

            }

            return ds;

        }

 

接下来我们来看以下场景:

用户登录,账号密码存在User表中,该表字段为ID,Name,PassWord三个字段,验证用户登录时直接传用户输入的用户名与密码给数据库,如果我们直接采用方式一,那么代码实现如下:

//获取传入的用户UserName与PassWord

string sql = \"SELECT *FROM User WHERE UserName = \'\"+UserName+\"\' ANDPassWord = \'\"+PassWord+\"\'\";

//其他处理代码

假设我们的账户名称是admin,密码是123,那么构造出的sql就是:

SELECT * FROM User WHEREUserName = ’admin’ AND PassWord = ’123’

执行结果看起来没有问题,但是如果这个时候我们输入的密码是 ‘’or 1=1时,那么实际执行的SQL就变成了:

SELECT * FROM User WHEREUserName = ’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等操作的权限。

 

四.URL安全测试:

1.MVC下的URL构成:

1).使用Get方式的URL构造方式:

~/控制器名/调用的方法?入参1=参数1&……&入参n=参数n,例如:

http://localhost:10344/AbnormalPunch/ApplySubmit?ID=13244&EmployeeID=1D2DE5AD8BC74E2A9CA70DE3567472EB

可以看到,在不经过处理的情况下,Get方式生成的URL可以看到数据和参数

2).使用Post方式的URL构造方式:、

~/控制器名/调用的方法,入参则放在报文实体主体部分中,例如:http://localhost:12688/Order/OrderList

通过接口测试手段可以获取到访问的入参:

{

        \"OrderType\":\"0\",

        \"QueryType\":\"1\"

}  

 

URL安全测试主要是基于URL的构成方式进行的测试,很多时候会涉及到和其他方向的交叉;了解各个原理后,就能比较全面的考虑问题了。

2.参数检查:主要就是检查URL或者主体报文中的参数

使用Get方式时,URL中显示的参数正确;敏感参数如用户名、密码不应被显示;

使用Post方式时,敏感参数应该进行加密处理

极端但是比较安全的处理方式是URL只显示网站地址,

3.根据URL的构成方式直接篡改URL:

我们回过头去看这个URL:

http://localhost:10344/AbnormalPunch/ApplySubmit?ID=13244&EmployeeID=1D2DE5AD8BC74E2A9CA70DE3567472EB   

这个URL的内容是的查询某个用户提交的某个申请的明细,URL的传入的ID为要查询的申请,EmployeeID是从Session中取的当前登录用户的ID。

那么我们可以基于以下场景篡改URL进行验证:

用户未登录时,直接输入该网址进行访问(涉及到登录验证);

其他用户登录时,输入这个网址(涉及到权限控制)

构造ID和EmployeeID为SQL注入的参数,然后访问(涉及到SQL注入)

以及稍后会涉及到的XSS、Session、Cookie等场景。

 

五.XSS

跨站脚本攻击(Cross Site Scripting),为了和层叠样式表css区分,简写为XSS。

1.原理

攻击者在网页中嵌入客户端脚本(例如JavaScript), 当用户浏览此网页时,脚本就会在用户的浏览器上执行,从而达到攻击者的目的。

例:

存在一个文本控件,其中value1from来自用户的输入:
<input type=\"text\" name=\"address1\" value=\"value1from\">

直接输入 \"/>那么实际执行的语句:

<input type=\"text\" name=\"address1\" value=\"\"/><script>alert(document.cookie)script>- \">

也可以将内容放到URL中进行访问:

http://localhost:10344/AbnormalPunch/ApplySubmit?ID=

我们可以看到,输入的内容直接改变了程序的执行代码,导致程序执行结果为攻击者想要的。

2.类型:

反射型XSS:需要欺骗用户进行操作才能触发XSS代码,主要威胁个体用户

持久性XSS:代码储存在服务器中,用户访问时即可直接触发XSS代码,威胁大量用户

3.解决思路:对数据进行html编码处理,保证用户输入的数据不会改变程序代码

\"安全测试基础_第2张图片\"\"安全测试基础_第3张图片\"

将重要的cookie标记为http  only,这样的话Javascript 中的document.cookie语句就不能获取到cookie了.

只允许用户输入我们期望的数据。 例如: 年龄的textbox中,只允许用户输入数字。而数字之外的字符都过滤掉。

过滤或移除特殊的Html标签, 例如: