网站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 getColumnListByType(String columnType) {
String jql = " FROM "+NewsColumn.class.getName(,)+" WHERE type=:type ";
List 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写啥都行,也是可以的,攻击者只需要把一个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

相关文章
|
7月前
|
安全 网络安全 数据库
Web安全防护的必要性与漏洞扫描技术
随着互联网的发展,Web应用程序的使用越来越广泛,但也带来了越来越多的安全威胁。因此,Web安全防护变得越来越重要。本文将介绍Web安全防护的必要性,并详细介绍各种漏洞扫描技术,以帮助您保护Web应用程序的安全。
207 2
|
5月前
|
SQL 监控 安全
网络安全中的安全漏洞管理与修复:技术深度剖析
【7月更文挑战第8天】安全漏洞的管理与修复是网络安全工作的重要组成部分。通过定期的安全审计、更新与补丁管理、漏洞扫描与评估、及时修复及持续监控与响应等措施,可以有效提升网络系统的安全性。然而,网络安全是一项长期而艰巨的任务,需要不断关注最新的安全动态和技术发展,持续优化安全策略和管理流程,以应对日益复杂的网络安全挑战。
|
17天前
|
SQL 安全 PHP
PHP安全性深度探索:防范常见漏洞与最佳实践####
本文深入剖析了PHP开发中常见的安全漏洞,包括SQL注入、XSS攻击、CSRF攻击及文件包含漏洞等,并针对每种漏洞提供了详尽的防御策略与最佳实践。通过实例分析,引导读者理解如何构建更加安全的PHP应用,确保数据完整性与用户隐私保护。 ####
|
4月前
|
存储 安全 网络安全
网络安全与信息安全:从漏洞到防范的全方位解析
【8月更文挑战第27天】在数字化时代,网络安全和信息安全的重要性日益凸显。本文将深入探讨网络安全漏洞、加密技术以及安全意识等方面的内容。我们将通过实例分析,揭示网络攻击者如何利用安全漏洞进行入侵,并介绍常见的加密技术及其应用。此外,我们还将强调提升个人和企业的安全意识对于防范网络攻击的重要性。无论你是IT专业人士还是普通用户,这篇文章都将为你提供宝贵的知识和技能,帮助你更好地保护自己的数字生活。
|
5月前
|
安全 算法 网络安全
网络安全与信息安全:从漏洞到防御的全方位解析
在数字化时代,网络安全和信息安全的重要性日益凸显。本文将从网络安全漏洞、加密技术、安全意识等方面进行全面的知识分享,旨在帮助读者更好地理解网络安全和信息安全的重要性,并掌握相应的防护措施。
63 0
|
7月前
|
安全 网络安全 数据安全/隐私保护
探索Web安全:强化防护与漏洞扫描技术
在当今数字化时代,Web安全已经成为企业和个人必须关注的重要问题。本文将介绍Web安全的重要性,以及如何通过强化防护与漏洞扫描技术来保护网站和应用程序的安全。同时,还将探讨一些最新的Web安全威胁和应对策略,帮助读者更好地了解和应对Web安全挑战。
107 0
|
7月前
|
云安全 安全 网络安全
网络安全为什么需要注重漏洞扫描
随着信息化不断深入发展,接入公共网络的数据资产越来越丰富,在为人们打开日常生活方便之门的同时,由于其价值逐渐显现,对威胁也更具吸引力,进而导致了风险也越来越高。下面德迅云安全就从网络安全的角度,探讨为什么我们需要进行漏洞扫描。
|
监控 安全 网络安全
web安全,系统网络安全,安全漏洞扫描等安全技术的详细说明以及分类?
web安全,系统网络安全,安全漏洞扫描等安全技术的详细说明以及分类?
|
安全 网络协议 应用服务中间件
主机安全漏洞解决方案
主机安全漏洞解决方案
主机安全漏洞解决方案
|
SQL 安全 前端开发
PHP网站漏洞修复公司对于业务漏洞的修复
最近,我们公司的在线业务系统遇到了一个更为棘手的问题。该公司的网站在线商城系统遭到黑客的入侵,数据库中的用户数据被黑客盗取。由于大部分的客户信息的泄露,公司接到了客户投诉说是电话经常被骚扰,以及受到广告短信。由于缺乏专业的安全技术没有安全方面的经验,PHP系统仅限于功能的实现。看来我需要学习安全方面的一些防止SQL注入攻击的,所以我必须下定决心,努力学习网站的安全。通过不断的探索,我找到了一个比较好的PHP安全方面的书籍“PHP安全之路”。在阅读的过程中,我会把学到的东西记下来,以便将来可以进行学习回忆。
247 0