51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 1570|回复: 1

web安全浅析

[复制链接]

该用户从未签到

发表于 2018-4-26 17:06:52 | 显示全部楼层 |阅读模式
1.1系统安全
1.1.1  客户端脚本安全

(1)跨站脚本攻击(XSS):

       XSS攻击,通常指黑客通过“html注入” 篡改了网页,插入了恶意的脚本,从而在用户浏览网页的时候,
控制用户浏览器的一种攻击。

       最常见的XSS攻击就是通过读取浏览器的Cookie对象,从而发起“cookie劫持”,当前用户的登录凭证存
储于服务器的session中,而在浏览器中是以cookie的形式进行存储的,cookie被劫持后,意味着攻击者可
以不通过密码而直接登录系统。我们也可以直接在浏览器中输入脚本javascript:alert(document.cookie)来
获取当前cookie值。

       目前防止“cookie劫持”的方法大致有:a. 输入检查,使用filter来过滤敏感的关键字;b. 将cookie与用户
ip地址进行绑定;c. 为cookie植入HttpOnly标识。

   本系统采用的是第3种方式:为cookie植入HttpOnly标识。一旦这个HttpOnly被设置,你在浏览器的
document对象中就看不到Cookie了,而浏览器在浏览的时候不受任何影响,因为Cookie会被放在浏览器
头中发送出去(包括ajax的时 候),应用程序也一般不会在js里操作这些敏感Cookie的,对于一些敏感的C
ookie我们采用HttpOnly,对于一些需要在应用程序中用js操作的cookie我们就不予设置,这样就保障了C
ookie信息的安全也保证了应用。

具体代码实现:在web服务器tomcat的配置文件server.xml中添加:

<Context docBase="E:\tomcat\apache-tomcat-6.0.24/webapps/netcredit" path="/netcredit" reloadab
le="false" useHttpOnly="true"/>
或者在项目的web.xml 配置如下:

复制代码
  1. <session-config>

  2.          <cookie-config>

  3.            <http-only>true</http-only>

  4.         </cookie-config>

  5.   </session-config>
复制代码

复制代码




图1-1 浏览器cookie截图

(2)跨站点请求伪造(CSRF):

       本系统采用了对抗CSRF最有效的防御方法:验证码。

1.1.2 服务器端应用安全

服务器端的安全相对于客户端来说显的更加的重要,因为服务器端的某个安全漏洞可能带来的是致命的
危险。因此我们对服务器端的安全更为的慎重和重视。

(1)SQL注入攻击:

Sql注入的的两个关键条件:第一个是用户能够控制输入;第二个是原本程序要执行的代码,拼接了用户
输入的数据。

根据上面两个关键条件,系统为防止sql注入使用了以下方法:

第一:使用预编译语句,这也是防御sql注入最有效的方法,完全摒弃代码的直接拼接所带来的危险。

复制代码
  1. public List<T> findByPage(final String hql, final Object[] values, final int offset,

  2.            final int pageSize) {

  3.        List<T> list = getHibernateTemplate().executeFind(new HibernateCallback(){

  4.            public Object doInHibernate(Session session)

  5.               throws HibernateException, SQLException{

  6.               Query query=session.createQuery(hql);

  7.               for (int i = 0 ; i < values.length ; i++){

  8.                   query.setParameter( i, values[i]);

  9.               }

  10.               if(!(offset==0 && pageSize==0)){

  11.                   query.setFirstResult(offset).setMaxResults(pageSize);

  12.               }

  13.               List<T> result = query.list();

  14.               return result;

  15.            }

  16.        });

  17.     return list;

  18.     }      
复制代码

复制代码
第二:关闭web服务器的错误回显功能,这样可以防止攻击者对系统进行攻击后,通过回显的详细错误
信息对攻击内容进行调整,对攻击者提供极大的便利。我们在项目的web.xml文件中添加以下示例代码:

复制代码
    <error-page>

        <error-code>400</error-code>

        <location>/error400.jsp</location>

    </error-page>

    。。。。。
复制代码
第三:数据库自身使用最小权限原则,系统程序不使用最高权限的root对数据库进行连接,而是使用能满
足系统需求的最小权限账户进行数据库连接,而且多个数据库之间使用不同的账户,保证每个数据库都有
独立对应的账户。

(2)文件上传漏洞:

文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过脚本文件获得了执行服务器端命令的能力,
这样将会导致严重的后果。而本系统内涉及到大量的图片格式文件上传,因此对于上传问题的处理非常谨
慎,并尽可能的达到安全标准。

本系统主要通过对上传文件详细的格式验证:

第一步:通过后缀名来简单判断文件的格式。

复制代码
  1. public static boolean isPicture(String pInput) throws Exception{

  2.       // 获得文件后缀名

  3.       String tmpName = pInput.substring(pInput.lastIndexOf(".") + 1,

  4.                                   pInput.length());

  5.       // 声明图片后缀名数组

  6.       String imgeArray [] = { "jpg", "png", "jpeg" };

  7.       // 遍历名称数组

  8.       for(int i = 0; i<imgeArray.length;i++){

  9.           // 判断符合全部类型的场合

  10.           if(imgeArray [i].equals(tmpName.toLowerCase())){

  11.               return true;

  12.           }

  13.         }

  14.       return false;

  15.     }
复制代码

复制代码
第二步:通过读取文件的前两个字符进行对比,例如png格式图片的前两个字符为8950,而jpg格式的图片
前两个字符为ffd8。

复制代码
  1. public static String bytesToHexString(byte[] src) {

  2.         StringBuilder stringBuilder = new StringBuilder();

  3.         if (src == null || src.length <= 0) {

  4.             return null;

  5.         }

  6.         for (int i = 0; i < src.length; i++) {

  7.             int v = src[i] & 0xFF;//byte to int

  8.             String hv = Integer.toHexString(v);

  9.             if (hv.length() < 2) {

  10.                 stringBuilder.append(0);

  11.             }

  12.             stringBuilder.append(hv);

  13.         }

  14.         return stringBuilder.toString();

  15.     }  
复制代码

复制代码


第三步:如果上传的为图片,则获取相应的高度和宽度,如果存在相应的宽度和高度则可认为上传的是图片。

复制代码
  1. public static boolean isImage(File imageFile) {

  2.         if (!imageFile.exists()) {

  3.             return false;

  4.         }

  5.         Image img = null;

  6.         try {

  7.             img = ImageIO.read(imageFile);

  8.             if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {

  9.                 return false;

  10.             }

  11.             return true;

  12.         } catch (Exception e) {

  13.             return false;

  14.         } finally {

  15.             img = null;

  16.         }

  17.    }
复制代码

复制代码


如果以上验证都成功通过,本系统在对文件进行存储时会将文件名进行重命名处理,并且设置相应的web服
务器,默认不显示目录。因为文件上传如果需要执行代码,则需要用户能够访问到这个文件,因此使用随机
数改写了文件名,将极大的增加攻击的成本,甚至根本无法成功实施攻击。

//对文件的名称进行重命名

StringBuilder sb = new StringBuilder().append(new Date().getTime()).append(".").append(fileMsg[1]);


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

x
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 2018-4-26 17:07:10 | 显示全部楼层
(3)认证与会话管理:

  认证实际上就是一个验证凭证的过程,因此我们对登录密码有着严格的规定:密码要求长度在8位以上并
且包含字母,数字,符号两种以上的组合。并将密码加密后再进行数据库的存储。为防止一些暴力破解手段,
又出于用户体验的考虑,本系统采用用户登录时默认不进行验证码的输入,但密码三次输入失败后需要进行验
证码的输入,连续五次输入错误后,该用户的ip地址将被封,可以在一段时间后自动解封或者后台管理员手动
解封。涉及到系统资金有关的操作,例如投标,我们还需要用户设置并提供支付密码,而提现等操作我们还配
备短信验证码功能。以此来增强验证的可靠性。

  当用户登录完成后,在服务器端会创建一个新的会话(Session),会话中保存着用户的状态和相关信息,
服务器端维护所有在线用户的Session,而浏览器则是将SessionId加密后保存在cookie中,这里就出现了前面提
到了“cookie劫持“问题,本系统通过将cookie中植入HttpOnly成功解决该问题。本系统还给Session设置了一个
有效时间,来保证在有效时间后Session将自动销毁,以防止Session长连接所带来的安全隐患。在web.xml文件
中添加以下代码:

<session-config>

     <session-timeout>30</session-timeout>

</session-config>
(4)访问控制:

访问控制实际上就是建立用户和权限之间的对应关系,本系统采用的是“基于角色的访问控制”,根据相应功能
模块的划分相应的权限,并将相应的权限分配给不同的角色,再将角色分配给用户,用户就拥有了该角色所持
有的权限。具体的设计与实现分析请见1.2 Annotation和Struts2拦截器实现基于角色的垂直权限管理。

1.2 Annotation和Struts2拦截器实现基于角色的垂直权限管理
1.2.1 模块的设计

以下是本系统的垂直权限管理模块的物理模型设计:



图1-2 权限管理模块物理模型

管理员与角色之间是多对多的关系,这样可以实现为一个管理员分配多个角色进行管理,而角色与权限之间也
是多对多的关系,权限是根据功能模块进行划分的,使得角色可以进行细粒度的权限分配。

4.3.2 模块的代码实现

首先声明一个注解类,该注解类是自定义的,根据我们需要的实现的功能进行相应注解的定义,使得在之后需要
注释的方法上使用相应注解,代码如下:

复制代码
  1. @Retention(RetentionPolicy.RUNTIME) //注解的存活时间,整个运行时都存活

  2. @Target(ElementType.METHOD) //此注解表示只能在方法上面有效

  3. public @interface Permission {

  4. /** 模块名 **/

  5. String model();

  6. /** 权限值 **/

  7. String privilegeValue();

  8. /*用于区分当前页面是dialog还是navTab*/

  9. String targetType();

  10. }

  11. 然后定义相应的拦截器类,并在struts2的配置文件struts.xml中进行拦截器的配置,为相应需要的类进行拦截验证,定义拦截器部分的核心代码如下:

  12. /**

  13. * 校验控制在方法上的拦截

  14. */

  15. @SuppressWarnings("unchecked")

  16. public boolean validate(Admin admin, ActionInvocation invocation, List<Role> roleList,

  17. Map session) {

  18. String methodName= "execute"; //定义默认的访问方法

  19. Method currentMethod = null;

  20. methodName = invocation.getProxy().getMethod(); //通过actionProxy,得到当前正在执行的方法名

  21. try {

  22. //利用反射,通过方法名称得到具体的方法

  23. currentMethod = invocation.getProxy().getAction().getClass().getMethod(methodName, new Class[] {});

  24. } catch (Exception e) {

  25. e.printStackTrace();

  26. }

  27. if (currentMethod != null && currentMethod.isAnnotationPresent(Permission.class)) {

  28. //得到方法上的Permission注解

  29. Permission permission = currentMethod.getAnnotation(Permission.class);

  30. //通过Permission注解构造出系统权限

  31. Systemprivilege privilege = new Systemprivilege(new SystemprivilegeId(permission.privilegeValue(), permission.model()));

  32. session.put("targetType", permission.targetType());

  33. //迭代用户所具有的具体权限,如果包含,返回true

  34. for (Role role : roleList) {

  35. RolePrivilege rolePrivilege = new RolePrivilege(privilege, role);

  36. if (role.getRolePrivileges().contains(rolePrivilege)) {

  37. return true;

  38. }

  39. }

  40. return false;

  41. }

  42. return true;

  43. }
复制代码

复制代码


本系统需要向权限表中添加相应的功能模块,为了有一个比较细的粒度,模块将根据功能进行划分,而权限则根
据按钮来进行细分:



图1-3 数据库截图

在定义了相应的权限后,我们需要在相应的执行方法体上面进行注释,使得拦截器进行拦截验证时能根据注释获
取该执行方法体的模块和权限类型:

@Permission(model="recharge", privilegeValue="recharge" ,targetType="dialog")
4.3.3 模块的实现效果

首先添加相应的员工:



然后新增相应的角色,填写角色名称并勾取相应的权限:



然后新增相应的用户,勾选该用户相应的角色,可以选择多个角色,并且选择相应用户对应的员工:



回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-3-29 23:22 , Processed in 0.066018 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表