【问题标题】:Reading SQL column name from querystring and building secure query from it从查询字符串中读取 SQL 列名并从中构建安全查询
【发布时间】:2009-07-28 19:23:57
【问题描述】:
我正在 C#/.NET2.0 中构建一个页面,该页面在 SQL 调用中动态更新不同的列,例如:
myajaxpage.aspx?id=1111&fieldname=title
构建 SQL 查询以从查询字符串中读取列名的正确方法是什么?首先这是一个好方法吗?
我试过了:
cmd.CommandText = "UPDATE MyTable SET +"Request.QueryString["fieldname"]"+ = @fieldvalue WHERE id = @id";
哪个有效但不安全,您能否建议如何使此查询安全?
【问题讨论】:
标签:
c#
sql
security
ado.net
【解决方案1】:
首先,考虑是否有其他方法可以做到这一点:公开实际的列名可能是个坏主意。现在恶意用户要做的工作就这么少了。
也就是说,我会考虑根据预期的值列表验证您的输入。如果 fieldname 的值是您不期望的值,您应该在它到达数据库层之前中止。
最后,您应该考虑使用方括号来引用字段名称。如果在输入中找到右方括号,则通过将其替换为双右方括号来对其进行转义:
[this [should]] be a valid name too]
【解决方案2】:
绝对不要像这样将查询字符串参数附加到 SQL 中。如果您要这样做,请改为支持查询字符串中的“友好”列名列表,然后将其映射到表中的真实字段名称 - 因此您也不会将任何有关您的实际架构的内容暴露给外部世界。
【解决方案3】:
您应该将字段名称从查询字符串中抽象出来。查询字符串可以包含一些表示字段的标识符,但没有理由将数据库布局的详细信息暴露在服务器之外。
任何来自浏览器的内容都不应在未经验证的情况下直接用于查询。您必须验证字段名称是您允许更改的字段之一,因此将独立标识符转换为实际字段名称的工作量大致相同。
【解决方案4】:
一点也不,你必须有一个可能的列的列表,除非用户可以输入他们想要的任何内容
var possibleColumns = New List<String>; // add pssobile columns here
if (possibleColumns.Contains(Request.QueryString["fieldname"])
cmd.CommandText = "UPDATE MyTable SET +"Request.QueryString["fieldname"]"+ = @fieldvalue WHERE id = @id";
else
Response.Write(" invalid query ");