如何保护加载数据本地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函数以及如何使用它们? [复制]