使用自定义公式防止 SQL 在报告生成器中注入

Preventing SQL injection in a report generator with custom formulas

我正在为我的客户构建自定义报告生成器,以便他们可以创建自己的报告。

概念是这样的:在一个控件table中,他们填写报表列的内容。每列可以包含来自不同数据源 (=tables) 的数据,或包含一个公式。

这是一个简化的示例:

Column | Source  | Year   | Account | Formula
----------------------------------------------
col1   | TAB1    | 2015   | SALES   | (null)
col2   | TAB2    | 2014   | SALES   | (null)
col3   | FORMULA | (null) | (null)  | ([col2]-[col1])

所以col1和col2从table的tab1和tab2中获取数据,col3计算差值。

存储过程然后创建动态 SQL,并传送报表数据。 结果 SQL 查询如下所示:

SELECT 
    (SELECT sum(val) from tab1 where Year=2015 and Account='SALES') as col1,
    (SELECT sum(val) from tab2 where Year=2014 and Account='SALES') as col2,
    (
       (SELECT sum(val) from tab1 where Year=2015 and Account='SALES')
       - 
       (SELECT sum(val) from tab2 where Year=2014 and Account='SALES')
    ) as col3 ;

实际上要复杂得多,因为参数比较多,我用的是coalesce()等

我最头疼的是公式。虽然它们为用户提供了一个非常灵活的工具,但它完全容易受到 SQL 注入的攻击。

只是想知道是否有一些简单的方法来检查可能的 SQL 注入参数。

否则我认为我需要限制系统对普通用户的灵活性,并且只有 "super users" 才能访问完整的灵活报告。

不完全是 - 许多注入涉及注释(注释掉常规语句的其余部分),因此您可以检查注释(-- 和 /*)和 ;签名(声明结束)。

另一方面,如果您允许您的用户将任何内容放入过滤器 - 为什么不应该有人将过滤器编写为 1 = (select password from users where username = 'admin') 来引发错误消息 Error converting 'ReallyStrongPassword' to integer'

此外,我想如果我看到你的查询,性能将是一个比注入更大的问题(如果你写它,它会读取 tab1 和 tab2 两次而不是只读取一次 'regular')。

编辑: 您可以检查 SQL 代码字作为 select、update、delete、exec ... 在 filter 参数中,以强化您的代码/查询。