简体   繁体   English

这是转义SQL查询参数的安全方法吗?

[英]Is this a secure method of escaping a SQL query parameter?

At my work it used to be tradition to form SQL queries by unsafely concatenating parameters into the query strings. 在我的工作中,通过不安全地将参数串联到查询字符串中来形成SQL查询是一种传统。 This leads, of course, to SQL injection vulnaribilities. 当然,这会导致SQL注入漏洞。 This wasn't considered a huge issue because all of the Java software in which this happens runs on closed networks of which all users are assumed to be trusted. 这不是一个大问题,因为所有发生这种情况的Java软件都在假定所有用户都受信任的封闭网络上运行。 Also, the queries are executed from client-side applications with database access, so a user could technically execute malicious queries anyway. 而且,查询是从具有数据库访问权限的客户端应用程序执行的,因此用户无论如何在技术上都可以执行恶意查询。

Nonetheless, it's planned to support prepared statements in the new version of the database layer. 尽管如此,仍计划在新版本的数据库层中支持准备好的语句。 In the meantime, I've written a small library on top of the existing database layer (which only supports executing a query from a SQL String, without the option for prepared statements or parameter escaping) that allows writing safe parameterized queries by escaping string parameters. 同时,我在现有数据库层之上编写了一个小库(该库仅支持从SQL String执行查询,而没有准备好的语句或参数转义的选项),该库允许通过转义字符串参数来编写安全的参数化查询。

As part of this library, I've wrote the following method that escapes a String literal. 作为该库的一部分,我编写了以下方法,以转义String文字。 I escape the same characters as PHP's addslashes function, but I try to avoid its multibyte character vulnerability by detecting supplementary (32-bit) characters: 我转义了与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();
}

My question is whether this method of escaping queries is secure enough (and I didn't oversee anything or made an implementation mistake). 我的问题是这种转义查询的方法是否足够安全(并且我没有监督任何事情或犯了实现错误)。 It can be assumed the input String is valid UTF-16. 可以假设输入的String是有效的UTF-16。 The DBMS's this will be used with are MySQL and Oracle. 将与MySQL和Oracle一起使用的DBMS。

如果没有ORM,准备好的语句或存储过程,我将对任何字符串SQL清理例程保持谨慎。

No. 没有。

Let's say you have an integer field which they input a PIN into: 假设您有一个整数字段,他们在其中输入了PIN:

"SELECT columns FROM table WHERE PIN = " + sanitizedstring “从表WHERE PIN =中选择列=” + sanitizedstring

and then for input you type in: 1234 OR 1 = 1 然后输入以下内容进行输入:1234 OR 1 = 1

And now your "pin" always is accepted, without any funny characters being used. 现在,您的“图钉”将始终被接受,无需使用任何有趣的字符。

This could work for fields besides ints too (since yes, you could validate that an int input is actually an int before handing it over to the SQL.) 这也可以用于除int之外的字段(因为是的,您可以在将int输入移交给SQL之前验证int输入实际上是int)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM