我意识到,在构建包含用户输入的查询时,参数化SQL查询是清理用户输入的最佳方式,但我想知道接受用户输入、转义任何单引号并用单引号包围整个字符串有什么错.以下是代码:

sSanitizedInput = "'" & Replace(sInput, "'", "''") & "'"

用户输入的任何单引号都将替换为双单引号,这将消除用户结束字符串的能力,因此他们可能键入的任何其他内容,如分号、百分号等,都将是字符串的一部分,而不是作为命令的一部分实际执行.

我们使用的是Microsoft SQL Server 2000,我认为单引号是唯一的字符串分隔符,也是转义字符串分隔符的唯一方法,因此无法执行用户键入的任何内容.

我看不出有任何方法可以对它发起SQL注入攻击,但我意识到,如果它像我认为的那样防弹,其他人可能已经想到了,这将是一种常见的做法.

这个代码怎么了?有没有办法让SQL注入攻击通过这种净化技术?利用这种技术的示例用户输入将非常有用.


更新:

I still don't know of any way to effectively launch a SQL injection attack against this code. A few people suggested that a backslash would escape one single-quote and leave the other to end the string so that the rest of the string would be executed as part of the SQL command, and I realize that this method would work to inject SQL into a MySQL database, but in SQL Server 2000 the only way (that I've been able to find) to escape a single-quote is with another single-quote; backslashes won't do it.

除非有办法停止单引号的转义,否则不会执行用户输入的其余部分,因为它们都将被视为一个连续字符串.

我知道有更好的方法来净化输入,但我真的更感兴趣的是了解为什么我上面提供的方法不起作用.如果有人知道针对这种净化方法发起SQL注入攻击的具体方法,我很乐意看到.

推荐答案

首先,这只是一种坏习惯.输入验证总是必要的,但也总是不确定的

关键是,你所做的任何黑名单(以及过于宽容的白名单)都可以绕过.我论文的最后一个链接显示了即使引用转义也可以绕过的情况.

即使这些情况不适用于你,这仍然是一个坏主意.此外,除非你的应用程序非常小,否则你将不得不处理维护问题,可能还要处理一定数量的治理问题:你如何确保它在任何时候、任何地方都能正常运行?

正确的方法是:

  • 白名单验证:类型、长度、格式或接受值
  • 如果你想被列入黑名单,那就go 吧.引用转义是好的,但在其他缓解措施的范围内.
  • 使用命令和参数对象来准备和验证
  • 仅调用参数化查询.
  • 更好的是,只使用存储过程.
  • 避免使用动态SQL,不要使用字符串连接来生成查询.
  • 如果使用SPs,还可以将数据库中的权限限制为仅执行所需的SPs,而不直接访问表.
  • 您还可以轻松验证整个代码库仅通过SPs访问数据库...

Sql相关问答推荐

Oracle SQL中的累计总数

如何在PostgreSQL中同时为id s列表执行多个update语句?'

如何在一个范围内进行分组.""范围值在范围表中定义

从2个表中查找每条记录的唯一最接近的日期匹配

SQL—如何根据2列填写缺失的值

如何根据计数和分组获取订单总数

PostgreSQL:使用JSONB中的字段使用jsonb_to_Records()填充记录

收到%1、%2或%2邮箱的唯一客户

正在try 从SQL获取最新的ID和一个唯一名称

根据开始日期和结束日期的差异计算每天的计费

将FLOAT转换为VARBINARY,然后再转换回FLOAT

输出连续出现两次以上的行

JSON_VALUE 不适用于提取的 json 中的嵌套路径

DB2 SQL查询结果多余数据

两个具有 NULL 值的表达式结果之间的差异

避免在SQL中使用具有相同条件的多个子查询

如何将输出转换为二维格式?

如何更改 duckdb R 中的数据约束

面对来自以下两个代码的不同输出

ACCESS SQL - 有没有办法使用通配符仅 Select 字段的特定部分?