在过去的工作中,我为我们的服务维护了一个允许临时查询的工具.它允许管理员在不必等待数周的代码部署的情况下请求报告(在部署需要数周的古怪时期).

我们不支持临时报表查询,方法是让服务接受任意字符串作为输入,并将它们作为SQL执行.这是非常不安全的,因为我相信你知道.

它的工作方式是报告查询存储在数据库中,以及所需的查询参数数量.

CREATE TABLE ManagerQueries (

id INT PRIMARY KEY,

query TEXT NOT NULL,

description TEXT NOT NULL,

num_params TINYINT UNSIGNED NOT NULL DEFAULT 0

);

INSERT INTO ManagerQueries

SET query = 'SELECT COUNT(*) FROM logins WHERE user_id = {0} AND created_at > {1}',

description = 'Count a given user logins since a date',

num_params = 2;

管理器前端可以通过其主键请求查询,而不是通过在Web请求中指定任意SQL字符串.

只有DBA以及可能知道如何编写安全查询的其他开发人员或经理才允许向此存储库添加新查询,因此可以确保查询经过测试和审查.

通过UI请求报表查询时,它强制用户提供查询参数的值.在我们的例子中,它从数据库中读取SQL,执行prepare()然后绑定execute()的值.所以SQL注入防御很满意.

在您的情况下,您的代码可能无法直接访问旧服务的数据库,因此您无法执行准备/执行并使用绑定参数.您必须提交具有集成值的静态查询.

在其他语言中,您可以通过转义使任何字符串值安全插入到SQL查询中.请参阅MySQL C API函数mysql_real_escape_string().

数字值更容易.你不必逃避任何事情,你只需要确保数值是真正的数字.将动态值转换为数字后,可以安全地插入到任何SQL字符串中.

不幸的是,我不认为golang SQL包支持任何转义函数.这已被要求作为一项功能,但据我所知,目前还没有支持的实现.见这里的讨论:https://github.com/golang/go/issues/18478

请注意,它比使用正则表达式替换有点棘手,因为您需要考虑多字节字符集.