Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这是转义SQL查询参数的安全方法吗?_Java_Mysql_Sql_Oracle_Security - Fatal编程技术网

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

Java 这是转义SQL查询参数的安全方法吗?,java,mysql,sql,oracle,security,Java,Mysql,Sql,Oracle,Security,在我的工作中,通过不安全地将参数连接到查询字符串来形成SQL查询曾经是一种传统。当然,这会导致SQL注入漏洞。这并不是一个大问题,因为所有发生这种情况的Java软件都运行在封闭的网络上,所有用户都被认为是可信的。此外,查询是从具有数据库访问权限的客户端应用程序执行的,因此用户可以在技术上执行恶意查询 尽管如此,它计划在新版本的数据库层中支持准备好的语句。同时,我在现有数据库层(只支持从SQL字符串执行查询,不支持预处理语句或参数转义选项)的基础上编写了一个小型库,该库允许通过转义字符串参数来编写

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

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

作为这个库的一部分,我编写了以下方法来转义字符串文本。我转义与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 str)
{
List-toEscape=Arrays.asList(“\”、“\ \”、“\0”);
StringBuilder结果=新建StringBuilder();
对于(int i=0;i如果(i='\uD800'&&c='\uDC00'&&next没有ORM、准备语句或存储过程,我会小心任何字符串SQL清理例程。

没有ORM、准备语句或存储过程,我会小心任何字符串SQL清理例程。

假设您有一个整数字段,他们在其中输入一个管脚:

“从表中选择列,其中PIN=“+sanitizedstring

然后输入以下内容: 1234或1=1

现在你的“pin”总是被接受的,没有任何有趣的字符被使用

这也适用于除int以外的字段(因为是的,您可以在将int输入提交给SQL之前验证它实际上是int。)

假设您有一个整数字段,他们在其中输入一个管脚:

“从表中选择列,其中PIN=“+sanitizedstring

然后输入以下内容: 1234或1=1

现在你的“pin”总是被接受的,没有任何有趣的字符被使用


这也适用于除int之外的字段(因为是的,您可以在将int输入提交给SQL之前验证它实际上是int)。

存储过程本身也存在风险。如果它们编写得不好,则可能会产生与java SQL注入相同的效果。@tom想详细说明一下“编写得不好”的含义吗"?除非该过程通过串联用户提供的值来动态创建SQL语句,否则我倾向于不同意。@Frank您正是在指出我的意思。我见过存储过程通过串联元素,然后使用
立即执行
来构建select。正确的方法显然是使用bind变量s(或者根本不使用
立即执行
),但初级开发人员并不总是这样做。因此,需要代码检查!存储过程本身就有风险。如果它们编写得不好,可能会产生与java sql注入相同的效果。@tom想详细说明一下“编写得不好”是什么意思吗?除非该过程通过串联用户提供的值来动态创建SQL语句,否则我倾向于不同意。@Frank您正是在指出我的意思。我见过存储过程通过串联元素,然后使用
立即执行
来构建select。正确的方法显然是使用bind变量s(或根本不使用
立即执行
),但初级开发人员并不总是这样做。因此需要代码检查!数据库连接和数据库表中使用的字符集/编码也很重要,因为“翻译”时可能会出现问题方案之间的字符。如果您能确保它们始终与Java的本机表示形式相同,您可能会减少攻击面。甚至不用麻烦了:到处都是字符串转义不好的示例。请尽快使用参数化查询路线。此外,更改代码也不会那么困难。另请参阅它的“否”您需要担心的只是sql注入。如果不使用绑定变量(无论如何,在Oracle上),您的sql缓存将被浪费,因为您会不断地硬解析每个“新的”我非常清楚参数化SQL是非常可取的。但是,这是一个临时措施,建立在现有数据库层之上,可以一直使用到该层(不支持参数化查询)数据库连接和数据库表中使用的字符集/编码也很重要,因为“翻译”时可能会出现问题方案之间的字符。如果您能确保它们始终与Java的本机表示形式相同,您可能会减少攻击面。甚至不用麻烦了:到处都是字符串转义不好的示例。请尽快使用参数化查询路线。此外,更改代码也不会那么困难。另请参阅它的“否”您需要担心的只是sql注入。如果不使用绑定变量(无论如何,在Oracle上),您的sql缓存将被浪费,因为您会不断地硬解析每个“新的”我非常清楚参数化SQL是非常可取的。但是,这是一个临时措施,建立在现有数据库层之上,可以一直使用到该层(不支持参数化查询)已更新。我发布的方法不打算由库用户直接使用。它在内部用于处理字符串类型的转义(我以不同方式处理整数)。库的可视API与