网站10大常见安全漏洞及解决方案

简介: 一般来说牛逼点的地方都会通过安全设备来确保网络环境的安全,所以之前我们也都认为程序员不需要过多的考虑网站安全问题。实际上随着做了几个事业单位的网站之后,也逐渐发现有些方面还是需要程序员注意的。 1. SQL注入 安全等级 几乎每一个网站后台开发人员都听到的一个词,并且都很敏感,但是不知道是什么原因造成的很多程序员却在实际开发过程中经常忽视这个问题。

一般来说牛逼点的地方都会通过安全设备来确保网络环境的安全,所以之前我们也都认为程序员不需要过多的考虑网站安全问题。实际上随着做了几个事业单位的网站之后,也逐渐发现有些方面还是需要程序员注意的。

1. SQL注入 安全等级

几乎每一个网站后台开发人员都听到的一个词,并且都很敏感,但是不知道是什么原因造成的很多程序员却在实际开发过程中经常忽视这个问题。前段时间部门一位新同事,据说是5年工作经验,在对他的代码做评审时,我们发现所有的DAO层实现都是直接拼接SQL和参数,总监多次提醒他这个问题,但他也没有发现,直到总监说出SQL注入这个词。

实际上这个漏洞很严重,一旦被注入成功,后果不堪设想,但这类问题处理起来还是蛮简单的,下面以JAVA为例举例说明

方案一: 编写拦截器过滤请求(不推荐),此方案建议只在对维护中项目或者代码结构比较乱的情况下使用,底层不容易修改或者不方便修改。此方案效率低,效果也不佳。

/**

  • 校验参数,判断是否包含sql关键字表达式
  • 此方法会有误伤
    */
private static boolean sqlValidate(String str) {  
    str = str.toLowerCase();//统一转为小写  
    String badSqlStr = "'|exec|execute|insert|select|delete|update|count|drop|chr|mid|master|truncate|char|declare|sitename|net user|xp_cmdshell|create|drop|"
                         +"table|from|grant|use|group_concat|column_name|1=1|=|"   
                         +"information_schema.columns|table_schema|union|where|*|"  
                      +"chr|mid|master|truncate|char|declare|or|;|,|like|//|/|%|#|-|--|+|";
    String badXssStr = "frame|iframe|script|javascript|=|<|>";
    
    //sql 关键词 有空格分隔
    String[] badSqlStrs = badSqlStr.split("\\|");  
    for (int i = 0; i < badSqlStrs.length; i++) {  
        if (str.indexOf(" "+badSqlStrs[i]) >= 0 || str.indexOf(badSqlStrs[i]+" ") >= 0) {  
            return true;  
        }  
    }

    } 
    
    return false;  

}

方案二:推荐方案,使用预编译的prepareStatement代替statement;使用框架中的setParameter设置参数,此方案可有效处理SQL注入问题。

@Override

  public List<NewsColumn> getColumnListByType(String columnType) {
        String jql = " FROM "+NewsColumn.class.getName(,)+" WHERE type=:type ";
        List<NewsColumn> list = entityManager.createQuery(jql).setParameter("type", columnType).getResultList();
        return list;
  }
  1. 验证码必须后台校验  安全等级

前段时间一客户说后台管理看到了一堆这样用户,/etc/init.d  /1=1  ./././ …. Windows/ ,本该截图的,后来处理了就给忘了~~~~,反正从注册内容来看,可以确定两点,通过注册机注册,想通过注册注入攻击。

通过机器注册:直接跳过了前端的表单校验,而恰巧这个项目在开发的时候,验证码只在前端做了校验,提交到后台没有做再一次的校验,也就是这个漏洞导致了这堆垃圾注册。

解决方案:前台提交数据到后台后做进一步校验,如验证码校验、数据格式校验、验重校验。

回想我也曾经用过这个漏洞…老东家海航集团2014年的时候,OA系统添加了登录需要手机短信验证,当时系统更新后第一个版本就是仅做了前台校验,这个漏洞无意中被我发现了,因为每天都要登录OA,每次都要短信实在太麻烦了,我就尝试模拟了个表单请求,重写原登录系统表单提交的脚本,在所有的验证我都直接返回true。很激动的是,一次就成功了,后来也分享给我们同事了,大家都很开心。但随后不久,系统就升级了,后台验证,你们懂得。当然对当时的信息部同事来说,我就是一个坏人……

  1. 防止表单重复提交   安全等级

防止表单重复提交其实网上有很多解决方案,并且现在主流的前端框架都可以在页面上做按钮控制,不过做为一个程序员,你们懂得,这并没有什么卵用。个人还是建议采用实际的后台验证法处理。从网上爬文,看到的靠谱的解决方案如下。

解决方案:token验证,请求页面时生成token并放在session中,提交表单到后台验证token,业务逻辑处理完之后,清除token。如果表单提交了一次,token就没了,再次提交就无法通过了。

方案分析:此方法和验证码基本上一致,如果验证码在每次表单提交后都清除一次,也能达到这样的效果。

其他建议:重要的表单页面提交后重定向,取消表单的autocomplete。

  1. 文件上传格式校验      安全等级

黑客攻击网站还有一个常见的方式就是通过文件上传漏洞,比如网站上传图片的功能没有严格校验后缀名。黑客可以通过此功能上传一些脚本文件,上传成功后,通过请求这些脚本文件运行脚本中的功能达到攻击的目的。

那么如果验证了上传文件的后缀名就可以吗?实际上并不是,举例说我们知道页面引入script标签时src写啥都行,比如http://www.baidu.com/123.jpg,也是可以的,攻击者只需要把一个script文件后缀名改为jpg即可通过后缀验证,后面一路畅通。所以这就提到了验证文件的真实格式。如何验证,网上一大堆…

解决方案:设置php文件、jsp文件不可直接被访问(不知道php可以不,jsp放在WEB-INF即可),这样攻击者上传此类文件也无法执行;通过文件头信息严格验证文件格式,从上传功能开始防范。

  1. 熟悉使用框架或数据库版本情况   安全等级

实际开发中,我们都使用一些开源框架,但这些框架也不是百分百完善的,比如webwork,struts2就经常爆出一些漏洞,这个需要开发者自行关注。

解决方案:根据官方发布的方案进行版本升级;根据公开的漏洞执行方式编写拦截器。

Struts2 s2-016 漏洞处理实例(项目结构不允许版本升级),拦截器,实际上官方的版本也是升级后过滤了一些参数。

@Override

   public void doFilter(ServletRequest request, ServletResponse response,
                 FilterChain filterChain) throws IOException, ServletException {
          HttpServletRequest req = (HttpServletRequest) request;
       HttpServletResponse res = (HttpServletResponse)response;
       //禁止页面被frame
       res.addHeader("x-frame-options","SAMEORIGIN"); 
          Map parameterMap = req.getParameterMap();
    for (Iterator iterator = parameterMap.keySet().iterator(); iterator.hasNext();) {
        String key = (String) iterator.next();
        if ((key.contains("redirect:")) || (key.contains("redirectAction:")) || (key.contains("action:"))) {
         res.sendError(HttpServletResponse.SC_FORBIDDEN, "forbidden");
         System.out.println("----------非法操作-----------");
            return;
        }
    }
    filterChain.doFilter(request, response);
   }
  1. 严禁在生产环境下使用缺省密码   安全等级

很多时候一些小网站,新人练手的网站(往往价格很便宜),在开发的过程中都要求很快,往往这些网站问题还是蛮多的。后台验证码处于关闭状态、账号密码常用admin/admin组合,看似方便了操作,实际是危险重重。甚至有时候,数据库链接密码都是root/空,这个危害大家都知道。由于没有验证码,用户密码又使用的缺省的,黑客爆破的概率异常的高,一旦获取了后台管理权限,剩下的就交给你了。

解决方案:通过配置测试模式和生产模式控制验证码验证,管理员账户必须使用非缺省加密处理,必要时使用物理验证。

  1. 服务器端口尽可能少开      安全等级

六月份一个客户的服务器被挂马了,服务器一直是他们自行维护,只在项目更新时给我们开放远程。无意中发现服务器防火墙竟然是关闭状态~~我的天呐,是不是所有端口都处于开放状态呐~~你们以为这就是惊喜,惊喜还在后面呢,客户提供的MySQL数据库用户名明码是root root,个人认为这个才是惊喜。root/root和root/空是一样的效果。分析了一下,防火墙关闭了,3306也就开了,黑客发现3306开着,root/root能连接,通过windows漏洞提升root用户为系统用户,bingo,竟然可以登录这台服务器欸,简直棒棒哒。

解决方案:防护墙打开,仅开放必要的端口如80,13389,设置远程登录IP白名单。再次强调不要用缺省账户。

  1. Options方法过滤        安全等级

这个问题网上提到的都是很严重,但现在并没有发现多少案例,或许处理方案比较简单吧。

解决方案:在web.xml添加配置

   

<security-constraint>     
<web-resource-collection>     
   <url-pattern>/*</url-pattern>     
   <http-method>PUT</http-method>     
<http-method>DELETE</http-method>     
<http-method>HEAD</http-method>     
<http-method>OPTIONS</http-method>     
<http-method>TRACE</http-method>
</web-resource-collection>     
   <auth-constraint>     
   </auth-constraint>     
</security-constraint>     
<login-config>     
    <auth-method>BASIC</auth-method>     
</login-config>
  1. XSS攻击、CSRF攻击    安全等级

XSSS攻击处理方案一般来说也是通过拦截器过滤请求参数,都是常规的处理方案。

package com.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**

  • 类说明
  • @author shy
  • @date 2016-4-21 下午03:34:26
  • @vesion $Revision$ $Date$
    */

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {

   HttpServletRequest orgRequest = null;  
     
public XssHttpServletRequestWrapper(HttpServletRequest request) {  
    super(request);  
    orgRequest = request;  
}  

/** 
* 覆盖getParameter方法,将参数名和参数值都做xss过滤。<br/> 
* 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/> 
* getParameterNames,getParameterValues和getParameterMap也可能需要覆盖 
*/  
@Override  
public String getParameter(String name) {  
    String value = super.getParameter(xssEncode(name));  
    if (value != null) {  
        value = xssEncode(value);  
    }  
    return value;  
}  

/** 
* 覆盖getHeader方法,将参数名和参数值都做xss过滤。<br/> 
* 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/> 
* getHeaderNames 也可能需要覆盖 
*/  
@Override  
public String getHeader(String name) {  

    String value = super.getHeader(xssEncode(name));  
    if (value != null) {  
        value = xssEncode(value);  
    }  
    return value;  
}  

/** 
* 将容易引起xss漏洞的半角字符直接替换成全角字符 
* 
* @param s 
* @return 
*/  
private static String xssEncode(String s) {  
    if (s == null || "".equals(s)) {  
        return s;  
    }  
    StringBuilder sb = new StringBuilder(s.length() + 16);  
    for (int i = 0; i < s.length(); i++) {  
        char c = s.charAt(i);  
        switch (c) {  
        case '>':  
            sb.append('>');//全角大于号  
            break;  
        case '<':  
            sb.append('<');//全角小于号  
            break;  
        case '\'':  
            sb.append('‘');//全角单引号  
            break;  
        case '\"':  
            sb.append('“');//全角双引号  
            break;  
        case '&':  
            sb.append('&');//全角  
            break;  
        case '\\':  
            sb.append('\');//全角斜线  
            break;  
        case '#':  
            sb.append('#');//全角井号  
            break;  
        default:  
            sb.append(c);  
            break;  
        }  
    }  
    return sb.toString();  
}  


/** 
* 获取最原始的request 
* 
* @return 
*/  
public HttpServletRequest getOrgRequest() {  
    return orgRequest;  
}  

/** 
* 获取最原始的request的静态方法 
* 
* @return 
*/  
public static HttpServletRequest getOrgRequest(HttpServletRequest req) {  
    if (req instanceof XssHttpServletRequestWrapper) {  
        return ((XssHttpServletRequestWrapper) req).getOrgRequest();  
    }  

    return req;  
}  

}

CSRF攻击(这个还在学习中)

解决方案:从网上爬文看到的基本上是一致的,校验Referer,添加请求token验证,个人觉得此漏洞在大型系统中比较重视,小网站就呵呵了。

  1. frame引入控制      安全等级

这个不知道为什么会被列入网站安全问题中,一个客户网站找了第三方安全检测公司检测网站有这个漏洞,所以就不得不处理。网上抄来的。

Java代码(拦截器中使用):

response.addHeader("x-frame-options","SAMEORIGIN");

Nginx配置:

add_header X-Frame-Options SAMEORIGIN

Apache配置:

Header always append X-Frame-Options SAMEORIGIN

相关文章
|
4月前
|
存储 安全 测试技术
讲解移动应用的安全问题及如何防范。
移动应用安全涉及数据、认证、代码、网络及漏洞防护。关键措施包括数据加密、安全通信协议、认证授权、代码加固、安全测试及用户教育。开发者应关注最新安全威胁,与专业人士合作进行安全评估,确保应用安全。
42 5
|
4月前
|
安全 网络安全 数据库
Web安全防护的必要性与漏洞扫描技术
随着互联网的发展,Web应用程序的使用越来越广泛,但也带来了越来越多的安全威胁。因此,Web安全防护变得越来越重要。本文将介绍Web安全防护的必要性,并详细介绍各种漏洞扫描技术,以帮助您保护Web应用程序的安全。
150 2
|
10月前
|
安全 前端开发 JavaScript
互联网并发与安全系列教程(07) - 常见的Web安全漏洞(其它漏洞)
互联网并发与安全系列教程(07) - 常见的Web安全漏洞(其它漏洞)
89 0
|
2月前
|
SQL 监控 安全
网络安全中的安全漏洞管理与修复:技术深度剖析
【7月更文挑战第8天】安全漏洞的管理与修复是网络安全工作的重要组成部分。通过定期的安全审计、更新与补丁管理、漏洞扫描与评估、及时修复及持续监控与响应等措施,可以有效提升网络系统的安全性。然而,网络安全是一项长期而艰巨的任务,需要不断关注最新的安全动态和技术发展,持续优化安全策略和管理流程,以应对日益复杂的网络安全挑战。
|
17天前
|
运维 监控 安全
什么是基于风险的漏洞管理RBVM及其优势
RBVM(Risk-based Vulnerability Management)是基于风险的漏洞管理,RBVM方法不是简单地修补所有漏洞,而是关注那些实际可利用的、对组织构成风险的漏洞。这种方法通过分析内部资产、攻击者活动以及威胁情报馈送(特别是漏洞情报),来确定哪些漏洞是需要优先处理的。是一种更加智能化和策略性的方法来识别、评估、优先级排序和修复组织中的安全漏洞。
24 3
什么是基于风险的漏洞管理RBVM及其优势
|
3天前
|
SQL 安全 JavaScript
0x00.基础漏洞篇
0x00.基础漏洞篇
33 3
|
11月前
|
安全 Cloud Native Linux
开源软件的漏洞响应:应对安全威胁
开源软件的漏洞响应:应对安全威胁
79 0
|
12月前
|
监控 安全 网络安全
web安全,系统网络安全,安全漏洞扫描等安全技术的详细说明以及分类?
web安全,系统网络安全,安全漏洞扫描等安全技术的详细说明以及分类?
|
SQL 安全 数据可视化
MetInfo最新网站漏洞如何修复以及网站安全防护
齐博cms整站系统,是目前建站系统用的较多的一款CMS系统,开源,免费,第三方扩展化,界面可视化的操作,使用简单,便于新手使用和第二次开发,受到许多站长们的喜欢。开发架构使用的是php语言以及mysql数据库,强大的网站并发能力。于近日,我们SINE安全公司发现齐博cms又爆出高危的sql注入漏洞,关于该网站漏洞的详情,我们来详细的分析漏洞的产生以及如何利用。
201 0
MetInfo最新网站漏洞如何修复以及网站安全防护
|
SQL 安全 Java
网站漏洞修复之代码安全审计的解决方案站系统构建
在很多网站系统构建的一开始,最注重的就是网站程序代码的安全,我们SINE安全对甲方网站公司部署过很多的网站安全系统,之前有一些网站设计公司对于每个项目都会由专人去负责开发与设计,并与甲方网站公司进行沟通,每个技术的开发水平都不一样,有些网站技术有着十几年的开发经验,有的技术可能只有三四年的开发经验,所以开发出来的网站也都会有网站漏洞,比如:SQL注入漏洞,XSS跨站漏洞,远程命令执行漏洞,CSRF劫持漏洞,远程包含文件漏洞。
129 0
网站漏洞修复之代码安全审计的解决方案站系统构建