我正在开发一个相对较小的应用程序来与 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 执行恶意操作。
我看到了两种可能的方法来防止这种情况:
显然第二种方式是“便宜又快乐”的方式。但是鉴于上面关于凭据的声明,这些方法中的任何一种真的有必要吗?在迫使攻击者只使用备用攻击向量(与实际阻止攻击的努力相反?
最佳答案
使用 quote_identifier :
my $sql = "SELECT * FROM ".
$dbh->quote_identifier($cfg->{tablename}).
" WHERE foo = ?";
关于perl - 防止 SQL 表名注入(inject) - 多远?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1078397/