首页 > 解决方案 > MySql - 限制查询的 SELECT 子句中允许的计算

问题描述

在 mysql(5.6 版)中,我可以在我的SELECT子句中有公式/计算。

例如

SELECT (a*2) as x, (b+2) as y, sum(...) from table_name;

我也可以动态地传递计算。问题是我可以通过任何公式。有没有办法可以限制可以放入SELECT子句的内容?这可能会在注入攻击中被利用。

编辑:我可以这样说:

SELECT @@version, @@hostname, (a*2) as x, (b+2) as y, sum(...) from table_name;

这将暴露我的数据库版本和主机名。

标签: mysqlsqlsecurityselectsql-injection

解决方案


您的 HTTP 包装器听起来像是在设计上容易受到攻击。

如果您允许在 SQL 查询中执行不受信任的输入,这就是 SQL 注入的定义。

防止 SQL 注入的常见建议是使用查询参数。如果查询的动态部分等效于常量值(如带引号的字符串值、日期或数字文字),这很好,但它不适用于查询中可能需要的其他内容,例如一个列名,或者像你正在做的一个表达式。

@TimBiegeleisen 所描述的有时称为白名单

在白名单方法中,用户不能发送文字表达式。他们选择SQL 表达式,但只能从您在应用程序中控制的一组预定义表达式中进行选择。

这是 SQL 注入:

http://example.com/query?expr=(a*2) as x

这是白名单:

http://example.com/query?expr=1

其中“1”是硬编码的,用于选择您批准的表达式集中的第一个。您可以使用case语句、数组或类似的东西。

这可以用作白名单,因为如果用户尝试发送与您的语句或表达式数组中的键之一不对应的 expr id case,那么您的应用程序要么什么都不做,要么返回错误消息。

http://example.com/query?expr=(select password from users)

可以返回:

HTTP Status 400 Bad Request

这确实需要您拥有一些更强大的应用程序层。您必须编写代码来将表达式 id 映射到完整的表达式。


推荐阅读