【问题标题】:Reading SQL from local files, then eval-ing it. Safe?从本地文件中读取 SQL,然后对其进行评估。安全的?
【发布时间】:2018-07-03 16:54:35
【问题描述】:

我继承的代码在代码中具有非常大的 SQL 查询,通常在 heredocs 中,并且插入的变量将动态选择表或字段,如下所示:

    my $query = <<"SQL";
SELECT foo
FROM $some_table
WHERE bar = 'baz'
SQL

一些 SQL 查询非常大。问题是这使我的 Perl 文件不必要地冗长且难以阅读。代码分析和高亮工具也无法解析heredoc SQL。

我想将 SQL 保留在实际的 SQL 文件中,并像上面一样更改 Perl 代码以从本地目录读取文件:

my $query = eval(get_sql('some-file.sql'));

...eval-ing 以便扩展所有范围内的变量。

其中一些会发生在用户传递参数的 Web 可访问脚本中。绝对所有变量都被清除了,我在所有条件子句(WHERE、AND 等)中使用参数化语句

有很多关于使用eval() 的 FUD,所以我想知道:我的解决方案在 Web 应用程序中使用是否安全?

编辑...
我应该进一步提到get_sql() 函数可能看起来像这样:

sub get_sql {
    my ($filename) = @_;

    my $sql = slurp("/path/to/file/$filename.sql");
    my $query = qq|return qq{| . $sql . qq|};|;
    return $query;
}

我了解引号运算符不能出现在将要返回的 SQL 字符串中。

EDIT2...
考虑到任何数量的用例和/或约束,这是一个非常合理的问题。投反对票...没有理由,伙计们。

【问题讨论】:

  • sql-servermysql?
  • 为什么不使用存储过程而不是为您的 sql 使用文件?那么你的sql代码就在它所属的数据库中了。
  • 如果你只想扩展变量,你可以将它们保存在一个散列中,只需s/\$(\w+)/$variables{$1}/g
  • 我应该澄清这是 MySQL,而不是 SQL Server。我最初包含该标签是因为我认为它是针对通用“SQL 服务器”的,而不是针对 Microsoft 产品的,尽管问题涉及一般原则,实际数据库可能无关紧要。
  • 我不希望使用存储过程,原因不在这里也不在那里。我担心上述方法的安全性。

标签: mysql perl


【解决方案1】:

对于初学者来说,

my $query = <<"SQL";
SELECT foo
FROM $some_table
WHERE bar = 'baz'
SQL

存在注入错误。应该是

my $some_table_lit = $dbh->quote_identifier($some_table);

my $query = <<"SQL";
SELECT foo
FROM $some_table_lit
WHERE bar = 'baz'
SQL

您的模板系统非常糟糕。这相当于敲击螺钉的 CS。它使编写不安全的代码变得非常容易(正如您已经完成的那样),它引入了高耦合,并使代码非常脆弱。

您应该使用比您当前使用的更好的模板系统(有或没有eval)。

以下是使用Template-Toolkit的示例:

my $tt = Template->new();

$tt->process('some-file.sql', {
   some_table => $dbh->quote_identifier($some_table),
})
   or die $template->error();

SELECT foo
FROM [% some_table %]
WHERE bar = 'baz'

【讨论】:

  • 这可能是我的备份解决方案。我确实使用了模板工具包,我很欣赏这个建议。但是,我有兴趣了解 eval()-ing 解决方案不安全的特定情况。
  • 谢谢。扩展为字段名和表名的变量总是在代码中定义,从不反映原始用户输入,所以我认为它们是安全的,但使用 $dbh 方法作为一种习惯可能会很好。得分。
  • 呜呜。你会做错事,因为你认为它是安全的?始终将文本转换为您要插入的任何内容(SQL、HTML、URL 参数、sh 等)。如您所见,正确地做事并不难! (鉴于您在使用 eval 时犯了两个错误,我认为这样做更容易!)
  • @dmc7z:在被证明是无辜的之前,所有代码都是有罪的:除非您能证明不是这样,否则您应该假设您的代码是不安全的。如果您使用模板系统,这样的证明会更容易一些,但是询问任何给定方法可能不安全的示例是错误的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-19
相关资源
最近更新 更多