InfluxDB中用户传入measurement时如何防范SQL注入攻击
InfluxDB 1.x 动态传入measurement名的注入防范方案
你遇到的问题是InfluxDB 1.x的绑定参数能力仅支持WHERE子句中的值传参,不支持标识符(measurement、tag key、field key)位置的参数绑定,官方influx npm包自带的Influx.escape.measurement()方法转义逻辑不全,无法防御引号注入,可按以下层级落地防护:
第一层:优先使用白名单校验(最高优先级)
如果业务场景中可访问的measurement是固定有限集合,直接在拼接查询前做白名单校验,不合法直接拒绝,是安全性最高的方案:// 预定义所有允许访问的measurement const ALLOWED_MEASUREMENTS = new Set(['foo', 'cpu_load', 'memory_usage', 'disk_io']); if (!ALLOWED_MEASUREMENTS.has(userInputMeasurement)) { throw new Error('非法的measurement名称'); }第二层:实现合规的标识符转义逻辑(白名单无法覆盖场景使用)
InfluxQL对双引号包裹的标识符有明确的转义规则:仅需要转义两类字符:反斜杠\、双引号",转义方式为在待转义字符前加反斜杠。你可以自己实现可靠的转义函数,不要依赖npm包自带的不全的转义方法:function escapeInfluxIdentifier(identifier) { if (typeof identifier !== 'string') throw new TypeError('标识符必须为字符串类型'); // 注意转义顺序:先转义反斜杠,再转义双引号,顺序错误会导致转义失效 return identifier.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); }使用方式:
const safeMeasurementName = escapeInfluxIdentifier(userInputMeasurement); const query = ` SELECT * FROM "${safeMeasurementName}" WHERE time > ${'2022-06-21T18:27:16.041Z'} `;注意:原示例中时间值用双引号包裹是错误写法,InfluxQL中字符串/时间字面量需要用单引号包裹,双引号仅用于包裹标识符,这类值位置的参数优先用官方绑定参数传入,不要手动拼接。
第三层:权限兜底
给业务侧连接InfluxDB使用的账号配置最小权限,仅分配目标数据库的必要读写权限,不要授予管理员权限、跨库访问权限,即使出现极端的注入绕过情况,也能把影响范围降到最低。
内容的提问来源于stack exchange,提问作者greim
相关产品推荐
相关产品推荐

