我的sql jdbc方法是否安全,不受sql注入攻击?

时间:2014-04-19 11:38:16

标签: java sql jdbc sql-injection derby

我只是在谷歌搜索“如何将记录添加到带有'的数据库中”然后偶然发现我的程序可能存在漏洞,“sql注入”。我对此并不了解;我先在this page看到了它。人们在谈论参数化查询。

这是我在java中的代码:

 public int addItem(String name, String manufacturer, String desc, String id, String category, double cost) throws SQLException{
    String additem = "INSERT INTO item VALUES(" + addComma(returnInQuotes(id)) + addComma(returnInQuotes(name)) + addComma(returnInQuotes(manufacturer)) +
    addComma(returnInQuotes(desc)) + addComma(returnInQuotes(category)) + cost + ")";
    Statement statement = con.createStatement();
    return statement.executeUpdate(additem);
}

public int removeItemById(String id) throws SQLException{
    String removeitembyid = "DELETE FROM item WHERE id = " + returnInQuotes(id);
    Statement statement = con.createStatement();
    return statement.executeUpdate(removeitembyid);
}

private String returnInQuotes(String str){
    return  "'" + str + "'";
}

private String addComma(String str){
    return str + ",";
}

addCommareturnInQuotes是我制作的方法,因为我厌倦了在需要它们的方法中输入它们。

到目前为止,我已经尝试了没有引号的查询,如果没有它们,derby jdbc似乎无法工作。

2 个答案:

答案 0 :(得分:3)

当您直接使用sql语句的用户输入时,可以使用SQL注入,克服此漏洞的一种好方法是在Java中使用PreparedStatement

public int addItem(String name, String manufacturer, String desc, String id, String category, double cost) throws SQLException{
    String additem = "INSERT INTO item VALUES (?, ?, ?, ?, ?, ?)";
    PreparedStatement statement = con.prepareStatement(additem);
    statement.setString(1, id);
    statement.setString(2, name);
    statement.setString(3, manufacturer);
    statement.setString(4, desc);
    statement.setString(5, category);
    statement.setDouble(6, cost);
    return statement.executeUpdate();
}

public int removeItemById(String id) throws SQLException{
    String removeitembyid = "DELETE FROM item WHERE id = ?";
    PreparedStatement statement = con.prepareStatement(removeitembyid);
    statement.setString(1, id);
    return statement.executeUpdate();
}

您也不需要自己添加引号,它们会自动添加。

答案 1 :(得分:2)

不,你的代码不安全。您需要更改此方法以转义嵌入式撇号:

private String returnInQuotes(String str){
    return "'" + str.replace("'", "''") + "'";
}

否则,这样的id:

1'; delete from item where 'a' = 'a

如果您的驱动程序允许在一次调用中执行多个语句,则会产生灾难性后果。

但是,防止注入的最佳方法是使用预准备语句并设置参数值;司机为你处理报价。