易受SQL注入攻击?

时间:2017-08-05 19:08:57

标签: java mysql sql-injection

我目前正在创建一个使用MySQL的Java应用程序。

我已经读过,在某些情况下,您应该使用预准备语句来阻止SQL注入。

到目前为止,我还没有使用准备好的语句,我实际上有点担心我的代码可能容易受到SQL注入攻击。

执行MySQL查询的情况:

  • 从应用程序内部直接查询(所有使用的变量都在应用程序中定义)
  • API调用(另一个应用程序进行MySQL查询 - >所有使用的变量都在进行调用的应用程序内定义)

MySQL代码:

    public static void Update(final String qry) {

        try {
            Statement stnt = connection.createStatement();
            stnt.executeUpdate(qry);

        } catch (SQLException e) {
            e.printStackTrace();
        }

}
public static ResultSet Query(String qry) {
    final ResultSet rs;

        try {
            Statement stnt = connection.createStatement();
            rs = stnt.executeQuery(qry);
        } catch (Exception e) {
            e.printStackTrace();
        }

    return rs;
}

3 个答案:

答案 0 :(得分:3)

根据其他因素,您的应用程序可能仍然容易受到访问您应用程序环境的人的SQL注入攻击。

例如,如果代码中定义的变量从配置文件中获取其值,并且稍后成为SQL查询的一部分,则具有访问配置文件的攻击者可以通过更改配置内容来执行SQL注入攻击文件。其他应用程序也是如此:如果有一种方法可以改变构建SQL查询的变量内容,则可能会执行成功的SQL注入攻击。

使用预处理语句提供了针对注入的全面防御。但是,增加的复杂性非常值得给您带来麻烦,因为您可以通过相对简单的修复来填补巨大的安全漏洞。

答案 1 :(得分:1)

您可以发布String qry的示例吗?

一般情况下,如果您执行的查询的值不是在程序中定义但是从外部定义的,那么它可能很容易受到攻击。

例如:

如果您有String name = null;并且name是用户定义的,并且您将数据库推送到name,则可能存在漏洞。

您可以避免使用preparedStatement进行注入,因为您使用将值处理为字符串的方法设置参数。

示例:

try (Connection con = DriverManager.getConnection(JDBC_URL, JDBC_USERNAME, JDBC_PASSWORD)){
    try (PreparedStatement pst = con.prepareStatement(
                                "INSERT INTO " + TABLE_NAME
                                + "(id, date, ip, name) "
                                + "VALUES (?,?,?,?)")) {
    pst.clearParameters();

    pst.setInt(1, objectID);
    pst.setDate(2, (Date) objectDate);
    pst.setString(3, objectIP.getHostAddress());
    pst.setString(4, object.getName());

    int n = pst.executeUpdate();
    System.out.println("Inserted " + n + " rows.");

    } catch (SQLException e) {
        System.out.println("Error in insertion: " + e.getMessage());
    }
} catch (SQLException e){
    System.out.println("Problem with connection to db:" + e.getMessage());
}

TABLE_NAME作为静态字符串变量。

例如,尝试对名称进行的SQL注入将通过pst.setString,因此数据库不会将其视为查询,而只是作为要插入数据库的值。

答案 2 :(得分:0)

不确定哪个是你的问题,但是,你可能容易受到sql注入攻击,因为你有查询参数来自应用程序之外的场景(正如你解释的那样)。

无论如何,如果您在构建查询字符串时(或之前)已经在进行检查以防止出现这种情况,即使您没有使用预准备语句,也可能不容易受到攻击。

但我强烈建议使用带有绑定变量的准备好的语句