Java &引用;“地位”;可延伸至该方法,且在强制使用前未进行消毒。为什么?

Java &引用;“地位”;可延伸至该方法,且在强制使用前未进行消毒。为什么?,java,Java,我使用Intellij,但我不知道为什么总是出现以下错误: “状态”在方法外部提供,使用前未消毒 我的方法: ... public List getActionIdByTypeAndCodeAndStatus(String type, String code, String status) throws Exception { String sql = "select action_id from action where type = '" + type

我使用Intellij,但我不知道为什么总是出现以下错误:

“状态”在方法外部提供,使用前未消毒

我的方法:

...
    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();
            }
抛出错误的行是

 Query checkWriteLog = entityManager.createNativeQuery(sql);
问题:
你知道原因吗?如何修复它?

您正在通过关联调用方提供的字符串来创建SQL查询。您应该在运行查询之前转义并验证字符串,以避免错误

有关如何清理输入的信息,请参见

问题
您正在连接字符串以形成sql查询。这是很容易发生的

给定

我们可以传入以下字符串以获取状态,从而破坏您的数据库:

'; DROP TABLE action; --
为什么??",;将完成您的查询并运行它,然后我们提供另一个查询(;关闭第一个查询),即“DROP TABLE action”;最后我们添加两个破折号以忽略后面的所有内容

这会导致表操作的表删除,可能是灾难性的。 在网上阅读更多关于这方面的信息

解决方案
使用事先准备好的陈述,如:

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);
这是一种易于理解的方式,基本上将查询发送到数据库,并告诉它“运行它,但我会给你以后添加的值”,然后将值发送给它。这意味着您发送的任何内容都将放在“”之间,并且不会被视为查询**

**这不是实际发生的事情,而是理解它如何工作的一种方式。如果您需要实际的解释,请阅读wiki页面

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);