在我的工作中,通过不安全地将参数连接到查询字符串中来形成 SQL 查询是一种传统。当然,这会导致 SQL 注入漏洞。这并不是一个大问题,因为发生这种情况的所有 Java 软件都运行在所有用户都被信任的封闭网络上。此外,查询是从具有数据库访问权限的客户端应用程序执行的,因此用户在技术上无论如何都可以执行恶意查询。
尽管如此,它计划在新版本的数据库层中支持准备好的语句。同时,我在现有数据库层(仅支持从 SQL 字符串执行查询,没有准备好的语句或参数转义选项)之上编写了一个小库,允许通过转义字符串参数来编写安全的参数化查询.
作为该库的一部分,我编写了以下方法来转义字符串文字。我转义了与 PHP 的 addlashes 函数相同的字符,但我尝试通过检测补充(32 位)字符来避免其多字节字符漏洞:
private String escapeString(String str)
{
List<Character> toEscape = Arrays.asList('\'', '"', '\\', '\0');
StringBuilder result = new StringBuilder();
for(int i = 0; i < str.length(); ++i)
{
char c = str.charAt(i);
if(i < str.length() - 1 && c >= '\uD800' && c <= '\uDBFF')
{
char next = str.charAt(i + 1);
if(next >= '\uDC00' && next <= '\uDFFF')
{
// Two-char supplementary character. Escape neither.
result.append(c);
result.append(next);
++i;
continue;
}
}
if(toEscape.contains(c))
{
// Special character. Add escaping \.
result.append('\\');
}
// Copy character itself.
result.append(c);
}
return result.toString();
}
我的问题是这种转义查询的方法是否足够安全(而且我没有监督任何事情或犯了实施错误)。可以假设输入字符串是有效的 UTF-16。这将与 MySQL 和 Oracle 一起使用的 DBMS。