是这样,在写查询的条件的时候,有一个字段,输入格式是一个 comma-separated list。
我们从前是使用$符号,就像这样 v IN ($list$)。
但是这样明显有 SQL 注入的问题,虽然这个字段的输入是由程序员来控制的,我们团队仍然认为这个是一个潜在的风险点,想要避免使用$。因为随着代码的演变,情况可能变得不一样。
目前我们已经尝试过的方法:
在查询之前,用代码(比如正则表达式,或者假如不放心正则引擎的可靠性,自己写状态机)对 list 进行检查。因为仍然使用了$,所有仍然有潜在的风险。以后随着代码的增改,这个检查有可能会在某些路径下漏掉。
既然已经用代码了,直接把 list 转换为(v=1 or v=2 or v=3)这样的形式。使用这个方式,如果漏掉转换,那么我们很快会知道。但是仍然使用了$。
使用 find_in_set 等专用函数(我们现在用 MySQL )。我们一方面担心性能(虽然理论上优化器有足够的信息把它优化的跟上面的方法一样好)和平台锁定,一方面认为使用这种函数,导致我们的接口暴露了实现细节,不是正确的设计(比如,find_in_set 对 list 中的空格的处理跟我们的“设计”就不一样)。这个方法的好处是没有了注入的隐忧。
我现在心中最期望的方式,是使用类似 v = ANY(XXX(#field#))的方式。我是在网上看了 Postgres 相关的资料想到这条路子的。但是现在的问题是,我不知道这个 XXX 该是什么。或许它是 SQL 函数,或许它是 iBatis (或者 MyBatis )的某个功能。我甚至不知道这条路子在 MySQL 下是不是走得通。
欢迎大家给出意见
1
nybux 2017-06-07 15:54:59 +08:00
|