如何保护加载数据本地infile更新查询免受sql注入

Posted

技术标签:

【中文标题】如何保护加载数据本地infile更新查询免受sql注入【英文标题】:how to secure load data local infile update query against sql injection 【发布时间】:2015-03-08 06:09:01 【问题描述】:

在我的应用程序中,我需要提供上传 csv 和 excel 文件的可能性,然后用于更新数据库。这些文件包含 +/- 几百万行,所以我需要使用加载本地数据 infile:

$stmt1 = $dbh->prepare("CREATE TEMPORARY TABLE $prefixtempskuEAN LIKE $prefixskuEAN");

$stmt4 = $dbh->prepare("LOAD DATA LOCAL INFILE '/ama/$aa[0]/CustomerUpload/$a.csv' INTO TABLE $prefixtempskuEAN FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\"' (seller_sku, EAN, fallback)");

$stmt5 = $dbh->prepare("UPDATE $prefixskuEAN a LEFT JOIN $prefixtempskuEAN b ON a.seller_sku = b.seller_sku SET a.EAN = b.EAN, a.fallback = b.fallback WHERE a.seller_sku = b.seller_sku");

$stmt6 = $dbh->prepare("DROP TEMPORARY TABLE $prefixtempskuEAN");

$stmt4 中的变量是由我的程序设置的,所以它们不会成为问题,但我非常担心更新/插入值的安全性。有什么方法可以在不损失性能的情况下将这些值与加载数据本地 infile 一起转义?

【问题讨论】:

【参考方案1】:

如果我理解您的要求...没有必要“转义”LOAD DATA 语句读入的文件中的值。这些值被解释为数据,而不是 SQL 文本的一部分。

也就是说,如果从文件中读取的值类似于NOW(),它将被读取为字符串。如果将其存储到 VARCHAR 列中,则该字符串值将存储在该列中;该字符串的内容不会被解释为“调用 SQL 函数”。

LOAD DATA 类似于带有绑定占位符的预处理语句,例如:

INSERT INTO mytable (a,b,c) VALUES (?,?,?), (?,?,?), (?,?,?)

为占位符提供的值仅作为数据处理,它们不是 SQL 文本的一部分。

注意:这并不能保证存储在表中的值是“安全的”。 LOAD DATA 语句是安全的。该值完全有可能被其他语句提取,然后其他语句没有正确处理该值,因为它可能不安全,并造成严重破坏。


编辑

我的回答是,就从文件中读取的值而言,LOAD DATA 语句不易受到 SQL 注入的攻击。

澄清一下,这部分代码:

$stmt4 = $dbh->prepare("LOAD DATA LOCAL INFILE '/ama/$aa[0]/CustomerUpload/$a.csv' INTO

(可能)容易受到注入,来自 SQL 文本中包含的 $aa$a

【讨论】:

感谢您的回答!这意味着我不需要关心加载数据操作,但是之后的更新语句呢?如果我想得更远一点,在我的临时表中加载数据操作之后,我有一个未转义的查询字符串,然后在没有准备好的情况下运行更新查询(而且我找不到使用 $stmt5 的方法),那么我在这个查询中没有漏洞吗? 如果$stmt5 中存在漏洞,则在$prefix 变量的内容中。 UPDATE 语句处理的列中的值仅处理数据。 (我看到的唯一其他可能性是在 UPDATE 的目标表上存在易受攻击的 UPDATE 触发器的极端情况......触发器必须编码以准备和执行动态 SQL(在触发器中甚至允许这样做吗?)。 . UPDATE 语句本身不易受到存储在表中的“不安全”值的影响。 好的,再次感谢! $prefix 是用开关/白名单制作的,以避免这里的漏洞。

以上是关于如何保护加载数据本地infile更新查询免受sql注入的主要内容,如果未能解决你的问题,请参考以下文章

哪些是保护输入免受sql注入的最佳php函数以及如何使用它们? [复制]

在 PHP 中使用准备好的语句/存储过程时如何保护自己免受 SQL 注入?

我是不是足够保护我的网站免受 sql 注入?

sql参数保护你免受啥影响?

mysql 5.1.73 加载数据本地infile错误

PHP PDO:保护动态标识符免受 SQL 注入