我目前正在创建一个使用MySQL的Java应用程序。
我已经读过,在某些情况下,您应该使用预准备语句来阻止SQL注入。
到目前为止,我还没有使用准备好的语句,我实际上有点担心我的代码可能容易受到SQL注入攻击。
执行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;
}
答案 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
作为静态字符串变量。
pst.setString
,因此数据库不会将其视为查询,而只是作为要插入数据库的值。
答案 2 :(得分:0)
不确定哪个是你的问题,但是,你可能容易受到sql注入攻击,因为你有查询参数来自应用程序之外的场景(正如你解释的那样)。
无论如何,如果您在构建查询字符串时(或之前)已经在进行检查以防止出现这种情况,即使您没有使用预准备语句,也可能不容易受到攻击。
但我强烈建议使用带有绑定变量的准备好的语句