我使用Fortify 360来分析我的代码的安全性。Fortify已经确定了一个基于Hibernate的删除方法,以根据传入的对象执行删除。我对hibernate的理解是,hibernate将根据对象id ( id是一个数字)删除与对象关联的表中的一行。Fortify将其标记为SQL注入:Hibernate(输入验证和表示、数据流)。Fortify似乎不喜欢Hibernate使用未经验证的输入执行动态SQL语句。某种修正是必需的,还是只是作为一种减轻风险的警告?
public List findByItemProp(String propName, Object value){
try{
String qs = "from ItemTypes as model where model."+ propName +"= ?"; /* <-- flagged by Fortify */
Query qo = getSession().createQuery(qs);
qo.setParameter(0, value);
return qo.list();
} catch (){}
}发布于 2012-04-19 19:16:11
恐怕这份报告太缺乏细节,无法提供诊断。我不能在没有看到代码的情况下诊断这个问题。
如果您没有做任何事情来减轻静态分析警告,并且不知道该警告是否代表可利用的漏洞,则绝对不应该将其视为“减轻风险”。
我建议您从对自己进行SQL注入的教育开始,讨论安全性Hibernate,以及这个特定的警告。很可能,Fortify有在线帮助,它提供了有关此警告的详细说明;您应该从阅读开始。在Hibernate中的SQL注入上阅读下面的Fortify后台程序。我还推荐以下文章:SQL注入通常是如何在Spring/Hibernate设置中停止的、ORM注射和如何避免Hibernate中的SQL注入(一个Hibernate城市传说)。
更新(4/20):我看到您更新了问题以包含代码。谢谢。您提供的代码确实令人怀疑,我认为Fortify抱怨该代码是合理的。查看此代码,无法验证传递给createQuery()的查询是否为编译时常量,这就是Fortify发出警告消息的原因。
基本上,您显示的代码似乎是使用字符串连接来构造SQL查询。这很危险。如果propName可能受到攻击者的影响,那么您就有了一个可能的SQL注入漏洞。最好避免以这种方式构造SQL查询。
特别是,有一个神话认为使用准备好的语句(或参数化查询)本质上不受SQL注入的影响。这是正确的,但只有当查询本身是不能受攻击者影响的编译时常量时才是如此。如果您将不受信任的数据插入查询本身,那么在准备好的语句中使用它并不能神奇地保证您的安全。
因此,最佳实践是,当您使用准备好的语句时,确保查询可以很容易地被验证为编译时常量(并且不会受到攻击者的影响)。
总结一下经验的一般规则:(1)不要使用字符串连接来构建SQL查询。(2)当您希望对运行时值有某种依赖时,请使用准备好的语句来绑定运行时值。(3)确保用于创建准备好的语句的查询可以很容易地被验证为编译时常量。遵循这些实践将有助于避免SQL注入攻击。
发布于 2012-04-20 17:46:22
我从“如何避免Hibernate中的SQL注入”一文中得到了D.W.被引用的答案。
Fortify将查询字符串qs识别为易受SQL注入攻击。我不明白SQL注入是如何发生的,因为我正在使用setParameter(),就像Hibernate文章所建议的那样。最后,我意识到Fortify似乎认为propName是用户提供的数据。当我做了以下的改变
String qs = "from ItemTypes as model where model.stapler = ?";Fortify停止将此代码标识为SQL注入漏洞。
发布于 2012-04-20 21:21:59
"from ItemTypes as model where model."+ propNamefindByItemProp(“订书机=‘’;摆表式字体;-”,"");
噢,你的数据库来了,是的,它检测到字符串连接,不要那样做。它可能不够聪明,无法意识到它是方法调用中的一个参数,但它仍然是一种草率的做法,正如程序员所期望的那样,如果没有适当的文档,他们就必须对它进行消毒,而且最好确保它在方法本身中是干净的,因为当另一个开发人员做错了这件事时,您将不会感到无穷的麻烦。
https://security.stackexchange.com/questions/13955
复制相似问题