Aipoのサニタイジング処理

Aipoではユーザーによる入力ではhtmlタグの入力を受け付けておらず、サニタイジング(無効化)するようにしています。

データベースへのデータの投入・取り出しもわざわざStringのクラスではなくALStringFieldのクラスを使っているのはそのためであり、ALStringFieldを使うことで内部で勝手にサニタイジングしてくれるようになっています。

サニタイジングの処理自体は

https://github.com/aipocom/aipo/blob/master/core/src/main/java/com/aimluck/commons/utils/ALStringUtil.java

に書いてあります。

  /**
   * HTML文字列におけるメタ文字を置き換え、無害化します。
   * 
   * @param argStr
   *          メタ文字列
   * @return 変換後文字列
   */
  public static String sanitizing(String str) {
    if (str == null) {
      return "";
    }

    StringBuffer buff = new StringBuffer();

    int len = str.length();
    for (int i = 0; i < len; i++) {
      char originalCharacter = str.charAt(i);
      switch (originalCharacter) {
        case '<':
          buff.append("&lt;");
          break;
        case '>':
          buff.append("&gt;");
          break;
        case '\'':
          buff.append("'");
          break;
        case '\"':
          buff.append("&quot;");
          break;
        case '&':
          buff.append("&amp;");
          break;
        default:
          buff.append(originalCharacter);
      }
    }
    return buff.toString();
  }

逆に戻すメソッドはこちら

  /**
   * 無害化(サニタイジング)された文字列を復元します。
   * 
   * @param str
   *          サニタイジングされた文字を含む文字列
   * @return サニタイジング前文字列
   */
  public static String unsanitizing(String str) {
    if (str == null) {
      return "";
    }

    StringBuffer buff = new StringBuffer();
    int len = str.length();

    for (int i = 0; i < len; i++) {
      char originalChar = str.charAt(i);
      if (originalChar != '&') {
        buff.append(originalChar);
        continue;
      }
      if (len > i + 5) {
        if ("&lt;".equals(str.substring(i, i + 4))) {
          buff.append('<');
          i = i + 3;
        } else if ("&gt;".equals(str.substring(i, i + 4))) {
          buff.append('>');
          i = i + 3;
        } else if ("'".equals(str.substring(i, i + 5))) {
          buff.append('\'');
          i = i + 4;
        } else if ("&amp;".equals(str.substring(i, i + 5))) {
          buff.append('&');
          i = i + 4;
        } else if ("&quot;".equals(str.substring(i, i + 6))) {
          buff.append('\"');
          i = i + 5;
        } else {
          buff.append(originalChar);
          continue;
        }
      } else if (i + 4 == len) {
        if ("&lt;".equals(str.substring(i))) {
          buff.append('<');
        } else if ("&gt;".equals(str.substring(i))) {
          buff.append('>');
        } else {
          buff.append(str.substring(i));
          break;
        }
        i = i + 3;
      } else if (i + 5 == len) {
        if ("'".equals(str.substring(i))) {
          buff.append('\'');
        } else if ("&amp;".equals(str.substring(i))) {
          buff.append('&');
        } else {
          buff.append(str.substring(i));
          break;
        }
        i = i + 4;
      } else if (i + 6 == len) {
        if ("&quot;".equals(str.substring(i))) {
          buff.append('\"');
        } else {
          buff.append(str.substring(i));
          break;
        }
        i = i + 5;
      } else {
        buff.append('&');
      }
    }
    return buff.toString();
  }