ASP - SQL injection protection in the SELECT clause

浪子不回头ぞ 提交于 2020-01-16 04:04:16

问题


After getting great help in securing against SQL injection from classic ASP protection against SQL injection, I've encountered a major issue which cannot be solved using parameterized queries.

name = Trim(Request.QueryString("name"))
flds = Trim(Request.QueryString("flds"))
sql = "set rowcount 0 select " & flds & " from [TABLE] where Name = '" & name & "'"

From what I understand, a parameterized query will protect against SQL injection in the WHERE clause (in this case, the name field.

flds is a comma-separated list of parameters that the users wants returned. As it is obvious, it is very vulnerable to SQL injection.

One idea I have to secure my code is to have a statically generated dict of valid fields, split the flds string by ",", verify each one of the values against the dict, and construct the SQL query that will consist of all the fields that are present in the dict.

It seems to me that although this method will work for security, it will require me to modify the static list at every change in the database (however rare those are).

Are there better/proper ways of securing this code against SQL injection attacks?


回答1:


Create a split function in SQL Server (there are better ones for newer versions, but this is what you get in SQL Server 2000):

CREATE FUNCTION dbo.SplitStrings
(
   @List       NVARCHAR(4000),
   @Delimiter  CHAR(1)
)
RETURNS @Items TABLE
(
   Item NVARCHAR(4000)
)
AS
BEGIN
   DECLARE
       @Item VARCHAR(12),
       @Pos  INT;

   WHILE LEN(@List)>0
   BEGIN
       SET @Pos = CHARINDEX(@Delimiter, @List);

       IF @Pos = 0
           SET @Pos = LEN(@List)+1;

       SET @Item = LEFT(@List, @Pos-1);

       INSERT @Items SELECT LTRIM(RTRIM(@Item));

       SET @List = SUBSTRING(@List, @Pos + LEN(@Delimiter), LEN(@List));

       IF LEN(@List) = 0 BREAK;
   END
   RETURN;
END
GO

Then create a stored procedure:

CREATE PROCEDURE dbo.RunScaryQuery
  @columns NVARCHAR(4000),
  @table   NVARCHAR(255)
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @collist NVARCHAR(4000), @sql NVARCHAR(4000);

  SELECT @collist = COALESCE(@collist + ',', '') + c.name 
    FROM syscolumns AS c
    INNER JOIN dbo.SplitStrings(@columns, ',') AS s
    ON s.Item = c.name
    WHERE c.id = OBJECT_ID(@table);

  SELECT @sql = 'SELECT ' + @collist + ' FROM ' + @table
  -- where ...
  ;

  EXEC sp_executesql @sql;
END
GO

Now call that stored procedure from ASP with a properly parameterized command object.

This will ensure that your SQL query is generated only using column names that actually exist in the table. (Any nonsense will be ignored.)

This presumes that you will get at least one valid column name in the list.




回答2:


I'm at home, no db to test but this should do it Basically, get all the fields from the db that fit the where, get the requested fields in an array and compare the two lists, putting out only the requested fields.

name = Trim(Request.QueryString("name"))
flds = split(Trim(Request.QueryString("flds")),",")
sql = "set rowcount 0 select * from [TABLE] where Name = '" & name & "'"
set oRst = oConn.execute(sql)
on error resume next
do while not oRst.eof
  result    = ""
  separator = ""
  for each field in flds
    for each requested_field in flds
      if uCase(field.name) = uCase(trim(requested_field)) then
        result = result & separator & field.value
        separator = ","
      end if
    next
  next
  response.write result & "<br>"
  oRst.movenext
loop



回答3:


hm... so I'm going with another solution.

I first have an SQL query that return all the valid fields

select
   tcol.name
from
  sysObjects tobj
  join syscolumns tcol on tobj.id = tcol.id
where
  tobj.xtype = 'U'
  and tobj.name = '[TABLE]'

and then I validate every element as suggested by @peter. All the validated parameters are then used to build the query string, and name is passed as a parameter in the second query.

This seems to minimize the overhead and the strain on the database.




回答4:


Have a look at http://www.userfriendlythinking.com/Blog/BlogDetail.asp?p1=7013&p2=119&p7=3001

which shows usage of parameterized queries.



来源:https://stackoverflow.com/questions/11021669/asp-sql-injection-protection-in-the-select-clause

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!