相册

转义HTML中的特殊字符

今天跨站点脚本如此流行,其中一个原因就是我们的程序员的防御不够完善甚至没有防御,在表单提交的程序中,
我们有必要过滤某些特殊字符,防止诸如sql注入,

<script>

恶意攻击等方式,在java中替换字符串中的字符
如<,>,”,&…等是比较简单的,在这之前我们应该注意一点,java的字符串是不可变的,至于为什么,读读jdk
源码就知道了,有几个方面的原因,其实我们的

    String s="hello";

等同于

    String s=new String("hello");

每次new都是分配了一个新的存储空间,所有操作字符串的方法都不去改变字符串本身,而是返回一个新的字符串。
下面的代码:

    String s1="hello";
    String s2=s1+ " World";

s1是不可修改的,所以第二行代码首先要生成s1的副本,然后将” World”追加到该副本,然后这个副本就会被废弃,
在循环中执行重复性的字符串操作时我们应该使用StringBuffer,而不是String,因为String对象总是会生成和
复制临时对象,这带来了额外的内存开销。

下面的类是一个过滤<, >, “, &四个符号:

package com.connove.util;

import java.util.StringTokenizer;

public class StringUtilities {
  // Given a string, this method replaces all occurrences of
  // '<' with '&lt;', all occurrences of '>' with
  // '&gt;', and (to handle cases that occur inside attribute
  // values), all occurrences of double quotes with
  // '&quot;' and all occurrences of '&' with '&amp;'.
  // Without such filtering, an arbitrary string
  // could not safely be inserted in a Web page.
  public static String filter(String input) {
    if (!hasSpecialChars(input)) {
      return input;
    }
    StringBuffer filtered = new StringBuffer(input.length());
    char c;
    for (int i = 0; i < input.length(); i++) {
      c = input.charAt(i);
      switch (c) {
      case '<':
        filtered.append("&lt;");
        break;
      case '>':
        filtered.append("&gt;");
        break;
      case '"':
        filtered.append("&quot;");
        break;
      case '&':
        filtered.append("&amp;");
        break;
      default:
        filtered.append(c);
      }
    }
    return filtered.toString();
  }

  private static boolean hasSpecialChars(String input) {
    boolean flag = false;
    if (input != null && !input.isEmpty()) {
      char c;
      for (int i = 0; i < input.length(); i++) {
        c = input.charAt(i);
        switch (c) {
        case '<':
          flag = true;
          break;
        case '>':
          flag = true;
          break;
        case '"':
          flag = true;
          break;
        case '&':
          flag = true;
          break;
        }
      }
    }
    return flag;
  }
  public static String makeList(String listItems) {
    StringTokenizer tokenizer=new StringTokenizer(listItems,", ");
    String list="<ul>";
    while(tokenizer.hasMoreTokens()) {
      list=list+"<li>"+tokenizer.nextToken()+"</li>";
    }
    list+="</ul>";
    return list;
  }
}

下面是提交代码的截图:

输出结果如下所示:

// code
  public static String filter(String input) {
    if (!hasSpecialChars(input)) {
      return input;
    }
    StringBuffer filtered = new StringBuffer(input.length());
    char c;
    for (int i = 0; i < input.length(); i++) {
      c = input.charAt(i);
      switch (c) {
      case '<':
        filtered.append("&lt;");
        break;
      case '>':
        filtered.append("&gt;");
        break;
      case '"':
        filtered.append("&quot;");
        break;
      case '&':
        filtered.append("&amp;");
        break;
      default:
        filtered.append(c);
      }
    }
    return filtered.toString();
  }

发表评论