StringEscapeUtils的使用

StringEscapeUtils是apache commons-lang(2.3以上版本)为我们提供了一个方便做转义的工具类,可以对HTML、Unicode、JavaScript等字符串进行转义,主要是为了防止sql注入,xss注入攻击的功能。

应该说,您即使没有处理 HTML 或 JavaScript 的特殊字符,也不会带来灾难性的后果,但是如果不在动态构造 SQL 语句时对变量中特殊字符进行处理,将可能导致程序漏洞、数据盗取、数据破坏等严重的安全问题。网络中有大量讲解 SQL 注入的文章,感兴趣的读者可以搜索相关的资料深入研究。

虽然 SQL 注入的后果很严重,但是只要对动态构造的 SQL 语句的变量进行特殊字符转义处理,就可以避免这一问题的发生了。来看一个存在安全漏洞的经典例子:

SELECT COUNT(userId) FROM t_user WHERE userName='”+userName+”' AND password ='”+password+”';

以上 SQL 语句根据返回的结果数判断用户提供的登录信息是否正确,如果 userName 变量不经过特殊字符转义处理就直接合并到 SQL 语句中,黑客就可以通过将 userName 设置为 “1' or '1'='1”绕过用户名/密码的检查直接进入系统了。

所以除非必要,一般建议通过 PreparedStatement 参数绑定的方式构造动态 SQL 语句,因为这种方式可以避免 SQL 注入的潜在安全问题。但是往往很难在应用中完全避免通过拼接字符串构造动态 SQL 语句的方式。为了防止他人使用特殊 SQL 字符破坏 SQL 的语句结构或植入恶意操作,必须在变量拼接到 SQL 语句之前对其中的特殊字符进行转义处理。spring 并没有提供相应的工具类,您可以通过 jakarta commons lang 通用类包中(spring/lib/jakarta-commons/commons-lang.jar)的 StringEscapeUtils 完成这一工作:

org.apache.commons.lang.StringEscapeUtils 总共提供了以下几个方法:

SqlEscapeExample示例

public static void main(String[] args) {
    String userName = "1' or '1'='1";
    String password = "123456";
    userName = StringEscapeUtils.escapeSql(userName);
    password = StringEscapeUtils.escapeSql(password);
    String sql = "SELECT COUNT(userId) FROM t_user WHERE userName='" + userName + "' AND password ='" + password + "'";
    System.out.println(sql);
}
输出
SELECT COUNT(userId) FROM t_user WHERE userName='1'' or ''1''=''1' AND password ='123456'

其他示例:

public static void main(String[] args) {
    String str = "中国";
    System.out.println("用escapeJava方法转义之后的字符串为:" + StringEscapeUtils.escapeJava(str));
    System.out.println("用unescapeJava方法反转义之后的字符串为:" + StringEscapeUtils.unescapeJava(StringEscapeUtils.escapeJava(str)));

    System.out.println("用escapeHtml方法转义之后的字符串为:" + StringEscapeUtils.escapeHtml(str));
    System.out.println("用unescapeHtml方法反转义之后的字符串为:" + StringEscapeUtils.unescapeHtml(StringEscapeUtils.escapeHtml(str)));

    System.out.println("用escapeXml方法转义之后的字符串为:" + StringEscapeUtils.escapeXml(str));
    System.out.println("用unescapeXml方法反转义之后的字符串为:" + StringEscapeUtils.unescapeXml(StringEscapeUtils.escapeXml(str)));

    System.out.println("用escapeJavaScript方法转义之后的字符串为:" + StringEscapeUtils.escapeJavaScript(str));
    System.out.println("用unescapeJavaScript方法反转义之后的字符串为:" + StringEscapeUtils.unescapeJavaScript(StringEscapeUtils.escapeJavaScript(str)));
}
输出
用escapeJava方法转义之后的字符串为:\u4E2D\u56FD
用unescapeJava方法反转义之后的字符串为:中国
用escapeHtml方法转义之后的字符串为:中国
用unescapeHtml方法反转义之后的字符串为:中国
用escapeXml方法转义之后的字符串为:中国
用unescapeXml方法反转义之后的字符串为:中国
用escapeJavaScript方法转义之后的字符串为:\u4E2D\u56FD
用unescapeJavaScript方法反转义之后的字符串为:中国

相关阅读

Java代码Unicode转中文,中文转Unicode互相转换


赞(52) 打赏
未经允许不得转载:优客志 » JAVA开发
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏