UPDATE `company` SET `itnumber` = '595959' WHERE (id = 932)
因此,itnumber的价值来自该公司的用户输入。我想确保我能够阻止任何类型的SQL注入。所以用户输入595959并在动态查询中将该值构建为“595959”。是否仍然可以在此查询中进行SQL注入攻击?我知道使用prepare语句来防止sql注入,但是prepare语句可能需要为我的应用程序进行大量的开发工作,所以我正在寻找更少的时间和更简单的方法来修复我可以注入的大多数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());
答案 0 :(得分:8)
如果你只是简单地将输入连接到一个SQL字符串而不进行任何清理(并且简单地用单引号'
包围它不会使它干净),那么是的,它很容易被SQL注入。
请发布构造此SQL的代码以获得明确的答案。
更新
由于您使用的是Oracle SQL库中的getSQLvalue()
,因此可确保传入的值正确转义。这确实是安全的SQL注入,但它要求你记住在每个地方使用它。但是,使用参数可以确保相同,而不会有忘记转义SQL值的风险。
答案 1 :(得分:3)
是的,确实如此。例如:
UPDATE `company`
SET `itnumber` = '595959'; DROP TABLE company; --' WHERE (id = 932)
可能会奏效。
答案 2 :(得分:3)
我知道使用prepare语句 用来防止sql注入,但是 准备声明可能需要很多 我的发展努力 申请,所以我在寻找更少 耗时且容易的方法 修复我的大部分sql语句 注射是可能的。
您会感到惊讶的是,从一开始就以right
方式实施解决方案所花费的时间更少。另外,为什么这比连接查询字符串更复杂?
PreparedStatement pstmt = con.prepareStatement(
"UPDATE `company` SET `itnumber` = ? WHERE (id = ?)"
);
pstmt.setString(1, "595959");
pstmt.setInt(2, 932);
另外,它具有以下优点:大多数现代驱动程序将缓存预准备语句的执行计划,因此这将加速其他查询。
答案 3 :(得分:1)
最安全的做法是为此创建一个存储过程,然后你的数据类型至少会保护你一点。
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
如果是这样的话; DROP TABLE公司; - 'WHERE(id = 932)被传递到@Company_Id,它将失败,因为数据类型是未命中匹配。
如果您要确定要更新哪些列,并且只有在更改了这些列时,您可以考虑执行 MERGE 而不是 UPDATE 语句。这样,您可以拉出记录的当前状态,只有在它们不相同的情况下才会更新。