Sql server 具有指定列的REST后端,SQL问题

Sql server 具有指定列的REST后端,SQL问题,sql-server,database,rest,Sql Server,Database,Rest,我正在使用一个新的REST后端与SQL Server对话。我们的RESTAPI允许调用者传入他们想要返回的列/字段??字段=id、姓名、电话 这个想法似乎很正常。我遇到的问题是动态生成SQL语句的阻力。传入的任何参数都将使用参数化查询传递到数据库,因此我不关心SQL注入 基本思想是将传入的列名注入SQL,如下所示: SELECT <column-names> FROM myTable ORDER BY <column-name-to-sort-by> LIMIT 1

我正在使用一个新的REST后端与SQL Server对话。我们的RESTAPI允许调用者传入他们想要返回的列/字段??字段=id、姓名、电话

这个想法似乎很正常。我遇到的问题是动态生成SQL语句的阻力。传入的任何参数都将使用参数化查询传递到数据库,因此我不关心SQL注入

基本思想是将传入的列名注入SQL,如下所示:

SELECT <column-names> 
FROM myTable 
ORDER BY <column-name-to-sort-by> 
LIMIT 1000
我们清理所有列名并验证它们在表中是否存在,以防止SQL注入问题。我们的大多数程序员都习惯于将所有SQL保存在静态文件中,然后从磁盘加载并将其传递到数据库。代码创建SQL的想法让他们非常紧张


我想我很好奇别人是否真的这么做了?如果是,你是如何做到的?如果没有,您如何管理传入的动态列和动态排序请求?

我认为很多人都这样做,尤其是在报告功能方面。为了安全起见,实际上应该做两件事:

参数化所有WHERE子句值 使用用户输入值选择正确的列/表名称,在sql语句中根本不使用用户值 为了详细说明第2项,我需要一个字典,其中键是一个可能的用户输入,值是一个对应的列/表名。您可以将此字典存储在任何需要的位置:配置文件、数据库、硬代码等。因此,当您处理用户输入时,只需检查字典中是否存在键,如果存在键,则使用该值将列名添加到查询中。这样,您只需使用用户输入来选择所需的列名,而不使用sql语句中的实际值。此外,您可能不想公开所有列。使用预定义的字典,您可以轻松控制用户可用列的列表


希望有帮助

我做了与马克西姆建议的类似的事情。在我的例子中,在对用户请求进行一些语法攻击和权限清理之后,直接从数据库系统表中提取密钥

下面的查询通过SQL处理类似条件的自然方式处理一些次要的注入问题。这还不至于处理每个字段的权限,因为有些字段是基于登录而被禁止的,但它提供了一种动态检索这些字段的非常基本的方法

CREATE PROC get_allowed_column_names
@input VARCHAR(MAX)
AS BEGIN
SELECT
  columns.name AS allowed_column_name
FROM
  syscolumns AS columns,
  sysobjects AS tables
WHERE
  columns.id = tables.id AND
  tables.name = 'Categories' AND
  @input LIKE '%' + columns.name + '%'
END
GO

-- The following only returns "Picture"
EXEC get_allowed_column_names 'Category_,Cat%,Picture'
GO

-- The following returns both "CategoryID and Picture"
EXEC get_allowed_column_names 'CategoryID, Picture'
GO

您能否详细说明-…是如何抵制动态生成SQL语句的。传入的任何参数都将使用参数化查询传递到数据库,因此我不关心sql注入。我想我在这里混合了两种不同的东西:1我们在将列名注入sql之前对它们进行清理。2我们对值使用参数化查询。。。其中name类似于@name,并通过参数化查询值传递@name。