perl - 防止 SQL 表名注入(inject) - 多远?

标签 perl security orm sql-injection dbi

我正在开发一个相对较小的应用程序来与 PostgreSQL 对话,并希望获得一些反馈,说明在防止 SQL 注入(inject)方面还有多远。

该应用程序在 Perl 中,不使用任何 ORM 模块(仅 DBI)。 SQL 语句是用占位符以典型方式构造的:

my $sql = "SELECT * FROM $cfg->{tablename} WHERE foo = ?";
my $sth = $dbh->prepare($sql);
$sth->execute('bar');

插入表名的原因是应用程序必须对多个表执行相同的操作,所有表都有一个列“foo”。

使用 ?占位符可防止大多数简单的 SQL 注入(inject)攻击。我的问题是关于表名,你不能使用占位符。该表来自配置文件,但应用程序支持 --configfile 开关以使用备用配置文件。

数据库凭据存储在配置文件中。因此,如果攻击者可以使用 $cfg->{tablename} 替换为恶意内容的配置文件(或替换默认文件),则可能会“诱骗”应用程序运行恶意代码。

对于攻击者来说,他们必须已经拥有有效的数据库凭据,否则应用程序将无法连接。如果他们有凭据,那么他们可以使用 DBI 编写自己的代码或使用 psql cli 执行恶意操作。

我看到了两种可能的方法来防止这种情况:
  • 切换到 ORM,在这种情况下,我会按照 $orm->get_class_for_table($cfg->{tablename}
  • 的顺序做一些事情
  • 在准备 SQL 语句之前使用正则表达式清理表名
  • 使用 $dbh->quote_identifier()

  • 显然第二种方式是“便宜又快乐”的方式。但是鉴于上面关于凭据的声明,这些方法中的任何一种真的有必要吗?在迫使攻击者只使用备用攻击向量(与实际阻止攻击的努力相反?

    最佳答案

    使用 quote_identifier :

    my $sql = "SELECT * FROM ".
      $dbh->quote_identifier($cfg->{tablename}).
      " WHERE foo = ?";
    

    关于perl - 防止 SQL 表名注入(inject) - 多远?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1078397/

    相关文章:

    java - 如何将 setAccessible 限制为仅 "legitimate"使用?

    security - POSTing 时是否可以在 Web 应用程序中使用 RSA 加密而不是 SSL?

    java - 使用 FLAG_SECURE 允许屏幕截图

    php - 获取 5 分钟前的行

    java - 使用 DB2 和 Java(以及 Hibernate?)将 XML 转换为关系型

    perl - 如何使用 tie() 仅为某些包重定向 STDOUT、STDERR?

    perl - 理解 Perl 中的引用

    Perl - 输出日志文件

    java - 如何通过 Hibernate 按页查询到表?

    linux - 如何在 Perl 中监控远程 Linux 机器并检索已安装的软件?