此查询是否可以进行SQL注入?
UPDATE `company` SET `itnumber` = '595959' WHERE (id = 932)
因此itnumber的值来自该公司的用户输入。我想确保我能够防止任何类型的SQL注入。因此,用户输入595959,我在动态查询中将该值创建为'595959'。这个查询中是否仍然可能存在sql注入攻击?我知道使用准备语句来防止sql注入,但准备语句可能需要我的应用程序的很多开发工作,所以我正在寻找更少的时间和更简单的方法来修复大部分可以注入的sql语句。此查询是否可以进行SQL注入?
StringBuffer sb = new StringBuffer();
sb.append(" UPDATE ");
sb.append(DB.quote(table));
sb.append(" SET ");
/* logic if column value has changed */
/* if yes */
sb.append(DB.quote(column.name));
sb.append(" = ");
sb.append(column.getSQLvalue());
sb.append(" WHERE (id = ");
sb.append(columns[0].getSQLvalue());
sb.append(")");
execute(sb.toString());
如果你只是串联输入到一个SQL字符串没有做任何清理工作(并简单地用单引号'
周围没有关系不能让它干净的),然后是的,这是容易受到SQL注入。
请发布构建此SQL的代码以获得明确答案。
更新:
由于您使用从Oracle SQL库getSQLvalue()
,这将确保在传递的值被正确转义。这对于SQL注入来说确实很安全,但它要求您记住在每个地方都使用它。但是,使用参数可以确保相同,但不会遗漏忘记SQL值的风险。
是的。例如:
UPDATE `company`
SET `itnumber` = '595959'; DROP TABLE company; --' WHERE (id = 932)
可能会工作。
我知道使用准备语句 用来防止SQL注入,但 准备语句可能会占用大量的 发展努力,为我的 的应用程序,所以我期待少 耗时和更简单的方法到 修复了大部分我的sql语句,其中 注入是可能的。
您会惊讶地发现,从一开始就实施解决方案right
的方式花费多少时间。另外,这是如何比连接查询字符串更复杂?
PreparedStatement pstmt = con.prepareStatement(
"UPDATE `company` SET `itnumber` = ? WHERE (id = ?)"
);
pstmt.setString(1, "595959");
pstmt.setInt(2, 932);
此外,它具有如下优点:最先进的驱动程序将缓存预处理语句的执行计划,因此这将加快其他查询。
真的最安全的做法是为此创建一个存储过程,那么你的数据类型至少可以保护你一点。
CREATE PROC usp_Update_itnumber_by_Company_Id
@itnumber int
, @Company_Id int
as
BEGIN TRAN
UPDATE [Company]
SET itnumber = @itnumber
WHERE id = @Company_Id;
COMMIT TRAN
这样if if; DROP TABLE公司; - 'WHERE(id = 932)被传入@Company_Id,它将失败,因为数据类型是未命中匹配。
如果你正在试图确定要更新的列,只有当他们已经改变了,你可以看看这样做而不是UPDATE语句的MERGE。通过这种方式,您可以获取记录的当前状态,只有当它们相同时才更新。
分析SQL注入是否可行需要查看生成SQL的* source *,而不是生成的SQL。 – Gabe 2011-02-28 20:31:24
为什么'java'标签? – 2011-02-28 20:35:52
@Alexander Pogrebnyak - 猜测,SQL字符串可能是在java应用程序中构建的。 – Oded 2011-02-28 20:36:35