我使用的是Intellij,但我不知道为什么总是会出现以下错误:
"状态"在方法外部提供,在使用前不进行消毒。
我的方法:
HashSet
抛出错误的行是
...
public List getActionIdByTypeAndCodeAndStatus(String type, String code, String status) throws Exception {
String sql = "select action_id from action where type = '" + type + "' and code = '" + code + "' and status = '" + status + "' ";
Query checkWriteLog = entityManager.createNativeQuery(sql);
return checkWriteLog.getResultList();
}
问题: 你知道原因吗?我该如何解决?
答案 0 :(得分:5)
您正在连接字符串以形成您的SQL查询。这很容易SQL injection attacks。
给定的
String sql = "select action_id from action where type = '" + type + "' and code = '" + code + "' and status = '" + status + "' "
我们可以传入以下字符串状态来破坏你的db:
'; DROP TABLE action; --
为什么呢? &#39 ;;将完成您的查询并运行它,然后我们提供另一个查询(;关闭第一个),这是" DROP TABLE操作;"最后我们添加两个破折号来忽略后面的所有内容
这会导致表操作的删除表,并且可能是灾难性的。 请在wiki page上了解详情。
使用如下的预备语句:
Query query = JPA.em().createNativeQuery("select action_id from action where type = ':type' and code = ':code' and status = :status ");
query.setParameter("type", type);
query.setParameter("code", code);
query.setParameter("status", status);
这以一种易于理解的方式,基本上会将查询发送到数据库并告诉它"运行它,但我会给你以后添加的值"然后将值发送给它。这意味着您发送的任何内容都将放置在""并且不会被视为查询。 **
**这不是实际发生的事情,它是了解它如何运作的一种方式。如果您需要实际解释,请阅读维基页面。
答案 1 :(得分:3)
您正在通过连接调用者提供的字符串来创建SQL查询。您应该在运行查询之前转义并验证字符串以避免SQL injection attacks。
有关如何清理输入的信息,请参阅this question。