这是一种逃避SQL查询参数的安全方法吗?

时间:2012-05-25 13:22:46

标签: java mysql sql oracle security

在我的工作中,过去通过将参数不安全地连接到查询字符串来形成SQL查询是传统的。当然,这导致SQL注入漏洞。这不是一个大问题,因为发生这种情况的所有Java软件都在封闭网络上运行,所有用户都被认为是可信任的。此外,查询是从具有数据库访问权限的客户端应用程序执行的,因此用户可以在技术上执行恶意查询。

尽管如此,计划在新版本的数据库层中支持预准备语句。与此同时,我在现有数据库层之上编写了一个小型库(它只支持从SQL字符串执行查询,没有预准备语句或参数转义的选项),允许通过转义字符串参数来编写安全的参数化查询

作为这个库的一部分,我编写了以下方法来转义String文字。我逃避与PHP的addslashes函数相同的字符,但我试图通过检测补充(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();
}

我的问题是这种转义查询的方法是否足够安全(我没有监督任何事情或者实施错误)。可以假设输入String是有效的UTF-16。 DBMS将与MySQL和Oracle一起使用。

2 个答案:

答案 0 :(得分:4)

如果没有ORM,预处理语句或存储过程,我会对任何字符串SQL清理例程保持谨慎。

答案 1 :(得分:1)

没有

假设您有一个整数字段,他们将PIN输入:

“SELECT FROM FROM table WHERE PIN =”+ sanitizedstring

然后输入您输入的内容: 1234或1 = 1

现在你的“别针”总是被接受,没有使用任何有趣的角色。

这也适用于除了int之外的字段(因为是的,你可以在将其输入SQL之前验证int输入实际上是一个int。)