andyyuduo 发表于 2018-10-23 11:33:09

SQL特殊字符转义

  应 该说,您即使没有处理 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 完成这一工作:
  清单 4. SqlEscapeExample
package com.baobaotao.escape;  
import org.apache.commons.lang.StringEscapeUtils;
  
public class 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);
  
    }
  
}
  事实上, StringEscapeUtils 不但提供了 SQL 特殊字符转义处理的功能,还提供了
HTML、XML、JavaScript、Java 特殊字符的转义和还原的方法。如果您不介意引入 jakarta commons lang
类包,我们更推荐您使用 StringEscapeUtils 工具类完成特殊字符转义处理的工作。


页: [1]
查看完整版本: SQL特殊字符转义