这种代码容易​​被SQL注入吗?

Is this kind of code prone to SQL injection?

我正在为我的学校做一个项目,我的任务是调试使用应用程序调用 HPE Fortify 发现的所有问题。应用程序生成的报告仅指出以下代码容易受到 SQL 注入:

        String sql = " select Distinct p1.desc1,p2.desc2 from parameter  p1"
          +" inner join  parameter p2"
          +" on p1.ParaCode1='CR_DERIVE' and p1.ParaCode2=p2.Desc2"
          +" inner join parameter p3"
          + " on p2.ParaCode3=p3.ParaCode1 and p3.ParaCode3=p2.Desc2"
          +" where p2.paracode1='ATTRIBUTE'"
          + " and p2.ParaCode2='" + ddl_attribute.SelectedValue + "'";

但不是下面的代码:

strSQL = "SELECT Paracode2 FROM Parameter WHERE Paracode1 = 'PROGMGR' AND Desc1 = '" + login + "' AND Status = 'A' ";

我想知道原因,因为我不清楚 SQL 注入,而且我是新手。感谢回复

您将一些应用程序变量连接到您的 SQL 查询字符串中,因此安全性取决于这些变量值的设置方式。它们是否来自某些不受信任的输入?或者它们是根据一些安全的应用程序数据设置的?

如果 HPE Fortify 分析了您的代码并知道您的 login 变量是如何赋值的,它可能能够判断在 SQL 表达式中使用它是安全的。然而它可能无法对 SelectedValue 变量做出结论,因此它假定它是不安全的,因此可能导致 SQL 漏洞。

Perl 语言做了类似的事情,但没有使用像 HPE Fortify 这样的工具。每个 Perl 变量要么是 "tainted" 要么是 "untainted" 取决于它从哪里获得它的值。因此,您可以判断变量是否可以安全地用于 SQL、eval() 或其他可能的代码注入情况。可惜更多的语言不支持类似的东西。

但我同意其他评论者的意见,即您应该学习使用查询参数。这很容易,而且很安全。如果你已经正确地平衡了引号中的引号,你就可以不再让眼睛疲劳了。

您的代码示例看起来可能是 Java。这是 Java 中的示例:

strSQL = "SELECT Paracode2 FROM Parameter"
       + " WHERE Paracode1 = 'PROGMGR' AND Desc1 = ? AND Status = 'A' ";

请注意,在 SQL 字符串中,参数的 ? 占位符周围没有单引号。您不得在占位符周围放置 SQL 引号。

PreparedStatement stmt = con.PreparedStatement(sql);
stmt.setString(1, login);
ResultSet rs = stmt.executeQuery();

有关帮助您了解 SQL 注入的更多信息,您可能会喜欢我的介绍 SQL Injection Myths and Fallacies, or the video of me delivering that talk: https://www.youtube.com/watch?v=VldxqTejybk