提问人:Hattie35 提问时间:7/30/2020 更新时间:8/4/2020 访问量:147
如果检查输入,是否需要参数化 SQL 搜索?
Do you need parameterized SQL searches if you check the inputs?
问:
我正在编写一个 R Shiny/SQLite 应用程序。在应用程序中,我有一个函数,它从我的 SQLite 数据库中的一个表中返回一列,该函数将表名作为输入。
在将查询发送到 SQLite 之前,该函数会检查表名是否等于允许用户访问的表名之一。但是,我没有使用参数化查询,因为我要更改的术语不是用于比较的变量,而是要从中提取信息的表的名称。(我想,无论如何,可能有一种方法可以通过参数化搜索来完成这项工作。
我的问题是,这是否对SQL注入是安全的?查询是否可以在从服务器到数据库的途中进行更改,或者仅从对服务器的 UI 输入进行更改?
(请耐心等待,我是SQLite的新手。
答:
假设您的查询按如下方式连接:
tbl <- "yourTable"
sql <- paste0("select * from ", tbl, " where some_col = 1")
那么应该没有 SQL 注入的机会,假设您检查传入的表名并验证它是否与白名单中的表名匹配。请注意,此步骤对于确保安全至关重要。假设您没有对传入的表名进行消毒。然后,考虑一下:
tbl <- "yourTable; delete from yourTable"
这将导致提交以下查询以供执行:
select * from yourTable; delete from yourTable where some_col = 1;
假设您的 SQLite 驱动程序允许执行多个 SQL 语句,上述技巧/技巧最终可能会从其中一个表的大部分中删除数据。
因此,只要您检查表名,您的方法应该是安全的。请注意,严格来说,表名本身不是参数化查询中的参数。相反,只有查询中的文本值是参数。
SQL注入的问题只是用户输入的问题。查询在从服务器到数据库的途中没有任何反应(理论上恶意软件可以改变它,但即使是参数化查询也无济于事)。
也就是说,如果您创建如下 SQL 字符串 (C#):
sql = "SELECT * FROM " + tableName;
然后,用户可能会输入“赞”tableName
MyTable; DROP TABLE MyTable
猜猜会发生什么。
因此,如果您检查表名称,则安全起见。
无论如何,都不能使用 SQL 查询参数来代替表名,因此将表名与已知授权表的列表进行比较是唯一的选择。
是的,这是安全的。如果您控制可插入 SQL 查询的值集,则可以防止未经授权的 SQL 注入。
请注意,SQL 查询的其他一些元素不能是参数:
- 任何标识符,例如表名、列名或架构名。
- 表达 式
- 谓词中的值列表。列表中的每个值使用一个参数。
IN ( ... )
- SQL 关键字。
查询参数只能用于代替单个标量值。也就是说,您将使用带引号的字符串文本、带引号的日期文本或数字文本。
评论