table 架构和名称的正则表达式验证
Regex validation of table schema and name
我有一个 API 对调用者指定的 table 执行一些查询。 table 名称通过字符串替换放置在查询中,因此存在 SQL 注入的风险。
示例:
tableName = req.body.tableName;
sql = "SELECT * FROM <<TABLE_NAME>>;";
sql = sql.replace("<<TABLE_NAME>>", tableName);
我需要保持此查询动态,因为我们不想在每次添加新 table 时都重新部署此代码。换句话说,我不能只维护一个有效 table 名称的列表。
因此,为了防止 sql 注入,对 table 名称进行正则表达式验证是否足够?我们可以确定 table 名称将始终采用 schema.table_name
格式,其中 table_name 将仅为 a-z、0-9、-、_
是否有任何 sql 注入可以绕过此 table 名称正则表达式?
^myschema\.[a-zA-Z0-9-_]+$
减号不能用作SQL中的标识符。对于 table 名称,我认为不会导致 SQL 注入攻击,但如果允许在列名称中使用减号,则可以注入减法。
在 MySQL 的情况下,以下 SQL 语句将 return 所有用户,而不仅仅是 'tom'。这是因为从字符串中减去时会发生隐式类型转换。
SELECT * FROM users WHERE myschema.user-0 = 'tom'
解决方法是排除减号或引用标识符。以下不会导致 SQL 注入攻击。
SELECT * FROM users WHERE `myschema`.`user-0` = 'tom'.
以上是MySQL的写法,标准SQL的写法如下
SELECT * FROM users WHERE "myschema"."user-0" = 'tom'
由于减号不是 table 名称中的有效字符,您可以将正则表达式更改为:
^myschema\.\w+$
\w
等同于 [a-zA-Z0-9_]
无注射风险
如果使用特殊语法,大多数数据库允许在 table 名称中使用特殊字符,甚至是空格和减号,例如
MySQL: `my stupid table-name!`
Postgres: "my stupid table-name!"
SQL Server: [my stupid table-name!]
一开始就允许在名称中使用非标准字符是不好的做法,在您的情况下拒绝此类名称会很好。
我有一个 API 对调用者指定的 table 执行一些查询。 table 名称通过字符串替换放置在查询中,因此存在 SQL 注入的风险。
示例:
tableName = req.body.tableName;
sql = "SELECT * FROM <<TABLE_NAME>>;";
sql = sql.replace("<<TABLE_NAME>>", tableName);
我需要保持此查询动态,因为我们不想在每次添加新 table 时都重新部署此代码。换句话说,我不能只维护一个有效 table 名称的列表。
因此,为了防止 sql 注入,对 table 名称进行正则表达式验证是否足够?我们可以确定 table 名称将始终采用 schema.table_name
格式,其中 table_name 将仅为 a-z、0-9、-、_
是否有任何 sql 注入可以绕过此 table 名称正则表达式?
^myschema\.[a-zA-Z0-9-_]+$
减号不能用作SQL中的标识符。对于 table 名称,我认为不会导致 SQL 注入攻击,但如果允许在列名称中使用减号,则可以注入减法。 在 MySQL 的情况下,以下 SQL 语句将 return 所有用户,而不仅仅是 'tom'。这是因为从字符串中减去时会发生隐式类型转换。
SELECT * FROM users WHERE myschema.user-0 = 'tom'
解决方法是排除减号或引用标识符。以下不会导致 SQL 注入攻击。
SELECT * FROM users WHERE `myschema`.`user-0` = 'tom'.
以上是MySQL的写法,标准SQL的写法如下
SELECT * FROM users WHERE "myschema"."user-0" = 'tom'
由于减号不是 table 名称中的有效字符,您可以将正则表达式更改为:
^myschema\.\w+$
\w
等同于 [a-zA-Z0-9_]
无注射风险
如果使用特殊语法,大多数数据库允许在 table 名称中使用特殊字符,甚至是空格和减号,例如
MySQL: `my stupid table-name!`
Postgres: "my stupid table-name!"
SQL Server: [my stupid table-name!]
一开始就允许在名称中使用非标准字符是不好的做法,在您的情况下拒绝此类名称会很好。