首页 > 解决方案 > 如何查询包含单引号的数据库字段?

问题描述

我在经典 ASP 中工作。我知道有一条记录与我的简单 SQL 选择查询相匹配。它有 ' 字符'。代码如下:

Fieldname = Replace(trim(Request.form("Fieldname")),"'","'", 1, 10)  
'replace the "'" up to 10 times with the ' code to avoid SQL issues, LOL.

SQL = "select id,fieldname from table where fieldname='"&Trim(Fieldname)&"'"

set rs = server.createobject("adodb.recordset")
rs.open SQL, Application("conn"), 1, 1
If not rs.eof then
    response.redirect "somepage.asp?QS=Fieldname_Exists_in_DB"
Else
    'Sample.hold the value in a hidden input field and pass it to the next page
End If

问题是,我知道 fieldname 和 fieldname 值在 MS-SQL 2016 服务器表中。我一直从中提取数据。与 SQL 数据库字段进行比较时,数据库字段中的'值与 Replaced FORM Fieldname 一样包含该值,因此它不应通过 IF NOT RS.EOF 问题。然而它每次都过去了。

我错过了什么?我在这个完全相同的应用程序的其他地方执行完全相同的查询,它的行为与预期的一样。

标签: sql-serverselectvbscriptasp-classic

解决方案


试图在评论中解释,但由于错过了这一点,我将尝试在这里举一个例子。

不信任用户输入

与库交互的经典 ASP 服务器端代码ADODB没有任何净化数据的概念。这意味着任何来自用户通过Request对象(如Request.Form("Fieldname"))的输入 都不应该被信任

Fieldname = Replace(trim(Request.form("Fieldname")),"'","'", 1, 10)
SQL = "select id,fieldname from table where fieldname='"&Trim(Fieldname)&"'"

此示例对SQL 注入攻击是开放的,通常是不好的做法,并且会导致安全漏洞,可以使用 Internet 上现成的脚本工具轻松利用这些漏洞。

手动清理数据

除了引入的安全漏洞之外,由于需要构造对字符串和其他数据类型的 SQL 调用(因提供者而异),它还使得查询数据变得更加困难。必须考虑可能被视为危险或可能破坏查询的各种字符组合可能是一项繁琐的任务,并且在ADODB已经有解决方案的情况下经常在野外看到。

参数化查询

图书馆ADODB有一个名为的内置对象ADODB.Command,可以消除所有这些麻烦。

使用问题中的示例,可以编写相同的查询,而不会出现手动清理数据或直接针对用户输入执行 SQL 的失败。

Const adCmdText = 1
Const adVarWChar = 202
Const adParamInput = 1

Dim Fieldname, SQL, cmd, rs, 
Fieldname = Trim(Request.Form("Fieldname") & "")

SQL = "SELECT id, fieldname FROM table WHERE fieldname = ?"

Set cmd = Server.CreateObject("ADODB.Command")
With cmd
  .ActiveConnection = Application("conn")
  .CommandType = adCmdText 'Also can use 1
  .CommandText = SQL
  Call .Append(.CreateParameter("@fieldName", adVarWChar, adParamInput, 255))
  Set rs = .Execute(, Array(Fieldname))
End With
Set cmd = Nothing

If Not rs.EOF then
    response.redirect "somepage.asp?QS=Fieldname_Exists_in_DB"
Else
    'Sample.hold the value in a hidden input field and pass it to the next page
End If

有用的链接


推荐阅读