我只是在谷歌搜索“如何将记录添加到带有'的数据库中”然后偶然发现我的程序可能存在漏洞,“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 + ",";
}
addComma
和returnInQuotes
是我制作的方法,因为我厌倦了在需要它们的方法中输入它们。
到目前为止,我已经尝试了没有引号的查询,如果没有它们,derby jdbc似乎无法工作。
答案 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
如果您的驱动程序允许在一次调用中执行多个语句,则会产生灾难性后果。
但是,防止注入的最佳方法是使用预准备语句并设置参数值;司机为你处理报价。