修复大型 ASP.NET C# Web 应用程序中的 SQL 注入表单
我必须修复一个容易受到 SQL 注入攻击的项目。
项目中每个页面的所有表单都没有使用参数化查询,而是简单的字符串查询。
对于示例,我有搜索页面,查看后面的代码,我发现有一个方法CreateQuery()
,它基于文本字段创建查询,例如:
string sQuery = "";
sQuery += "b.name like '%" + txtName.Text + "%'";
然后在 btnSearch_Click()
中,我有执行查询的方法:
query = CreateQuery();
var totalList = GetAllBlaBla(query);
我的问题是:
由于我有数百个表单和数千个 formText
以及需要 FIX 的值,是否存在 一样实现的“快速”解决方案
- 一个像全局函数 参数化查询或以某种方式处理情况?
- 由于在每个类中查询都是在
SubmitButton_Click()
代码隐藏方法中执行的,所以我可以处理这里的情况吗?当然是在每个类中? - 我是否应该修改每个表单以及表单代码隐藏中的每个条目来参数化 SQL 字符串,这将花费一百万年的时间?
(编辑)编码/解码输入值怎么样?因此上面的例子将是:
string sQuery = ""; var txt = var txt = HttpUtility.HtmlEncode(txtName.Text); sQuery += "b.name like '%" + txt + "%'";
这是一个可能的临时补丁吗?
5-(编辑)这是一个可能的解决方案,还是它根本不会改变任何东西?
cmd.Parameters.Add("@txtNameParameter", SqlDbType.VarChar);
cmd.Parameters["@txtNameParameter"].Value = txtName.Text;
sQuery += "b.name like '%" + (string)cmd.Parameters["@txtNameParameter"].Value + "%'";
问题是我必须返回一个字符串,因为处理查询的逻辑是在另一个将字符串作为查询的业务类中定义的,我不能给它 CommandType 或 SqlDataAdapter...
建议?
提前致谢。
I have to fix a project that is vulnerable to SQL injection.
All the forms in every page on the project do not use parametrized query but simply string query.
For example I have the search page, and looking at the code behind I see that there is a method CreateQuery()
that creates the query basing on the text fields as example:
string sQuery = "";
sQuery += "b.name like '%" + txtName.Text + "%'";
Then in the btnSearch_Click()
I have the method that does the query:
query = CreateQuery();
var totalList = GetAllBlaBla(query);
My question is:
Since I have hundreds of forms and thousands of formText
and values to FIX, is there a "quick" solution to implement like
- A global function that parametrizes the query or handle the situation in some way?
- Since in every class the query is executed in the
SubmitButton_Click()
code behind method, can I handle the situation here, of course in every class? - Should I modify every form and every entry in the form codebehind to parametrize the SQL string, that is gonna take one million of years?
(Edit) What about Encode/Decode input values? SO that the example above will be:
string sQuery = ""; var txt = var txt = HttpUtility.HtmlEncode(txtName.Text); sQuery += "b.name like '%" + txt + "%'";
Is this a possible temporary patch?
5- (Edit) Is this a possible solution, or it simply does not change anything?
cmd.Parameters.Add("@txtNameParameter", SqlDbType.VarChar);
cmd.Parameters["@txtNameParameter"].Value = txtName.Text;
sQuery += "b.name like '%" + (string)cmd.Parameters["@txtNameParameter"].Value + "%'";
The problem is that I have to return a string because the logic that handles the query is defined in another business class that takes a string as a query, I cannot give it a CommandType or SqlDataAdapter...
Suggestion?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
你已经知道有问题了; IMO,任何“快速”修复都可能减少攻击面,但不太可能防止坚决的滥用;简而言之,列入黑名单确实很困难,并且在黑帽(以及白帽示例)网站上可以轻松获得一些非常奇怪的输入。这些并不总是容易被识别为滥用行为。这不全是
' drop table Customers --
;p无论你做什么,我都建议你正确地做;参数。不过,像 dapper 这样的工具可能会减少您所需的代码:(
这比处理所有参数更容易手动等)
You already know there is a problem; IMO, any "quick" fix here is likely to reduce the attack surface, but is not likely to prevent determined abuse; simply, blacklisting is truly hard and there are some really bizarre inputs readily available on black-hat (and, as samples, on white-hat) sites. These are not always easily recognizable as abusive. It isn't all
' drop table Customers --
;pWHATEVER you do, I would advise doing it properly; parameters. Tools like dapper might reduce the code you need, though:
(which is easier than handling all the parameters etc manually)
修改每个查询+验证每个输入。
需要时间,但请考虑一下将维护“大型 Web 应用程序”并为其添加功能的人
(可能是你)。
Modify every query + validate every input.
Takes time but think about the guy who will maintain and add features to that "big web application"
(it may be you).
这将阻止用户看到错误,因此潜在的黑客根据他/她看到的错误消息几乎不知道如何利用此安全门
添加 Elmah 来记录错误。
重写每个查询以使用参数或使用 ORM。
任何基于 javascript 的解决方案都是无用的,因为“黑客”肯定知道如何禁用它。
This will prevent users to see the errors so a potential hacker would have very few clues how to exploit this security door, based on the error messages he/shes sees
Add Elmah to log errors.
Rewrite every query to use Parameters or use an ORM.
Any javascript based solution is useless, since a "hacker" for sure knows how to disable it.
简单方法
通过在项目中搜索
string sQuery = "
来估计替换数量。将其乘以您计划花费在修复单个查询上的时间(例如 5 分钟内修复一次,再加上茶歇时间) 修复)。每 10次
然后告诉管理层修复工作将是巨大的,给他们估计并去做。
当然你会头疼几天,但至少你的东西可以工作。
创造性的方式
如果你的意思是成百上千这样的表单具有几乎相同的代码(例如查询总是在
CreateQuery
中创建,在中执行>SubmitButton_Click
),我会考虑学习使用 Visual Studio 常规表达式 语法并制作一些非常准确的搜索和搜索结果。替换模式。这节省了我在一个项目中的工作时间,但您需要非常精确地使用正则表达式,并确保您了解自己在做什么。
同样,当您确定值得时,另一个选择是编写一个可以重写 C# 源代码的工具。
如果您需要的只是
The Plain Way
Estimate the number of replacements by searching the project for
string sQuery = "
. Multiply it by the time you plan spending on fixing a single query (e.g. one fix in 5 minutes, plus a coffee break each 10 fixes).Add time for testing the whole website.
Then tell management the fix is going to be huge, give them the estimate and just do it.
Surely you'll have headaches for a couple of days but at least you'll have the thing working.
The Creative Way
If you literally mean hundreds and thousands of such forms with nearly identical code (e.g. query always created in
CreateQuery
, executed inSubmitButton_Click
), I would consider learning to use Visual Studio regular expression syntax and crafting a couple of very accurate search & replace patterns.This saved me hours of work in one project, but you'll need to be really precise with regexps and make sure you understand what you're doing.
Another option, again, when you're sure it is worth it, is to write a tool that will rewrite C# sources.
If all you need is a simple transform like the one Marc mentioned, it could take a couple hours of work.
But you can fail miserably here so it's a risky route.
减少应用程序用于访问数据的数据库帐户的权限。希望它没有系统管理员。删除删除表的权限。如果该帐户仅用于数据检索,请删除所有更新数据的权限。您甚至可以考虑设置视图,锁定它们,并使用它们而不是直接表访问。
打开 ASP.NET 请求验证,如此处所述。这会自动检查所有流量中是否存在恶意字符序列。
如果可能,请考虑向 OnBeginRequest 的 Global 添加一个事件处理程序,用于检查传入数据并对所有输入执行白名单检查。不确定这对您的问题的映射效果如何,但好处是您只需在一次位置执行此操作,它将影响整个站点。
确保所有页面都调用 Page.Validate 以确保在服务器端也强制执行客户端验证。
开始为每个控件添加特定于字段的白名单验证的长期艰苦工作,并制定一个转向参数化数据库调用的长期计划。
Reduce the permissions of the database account that your application uses to access data. Hopefully it doesn't have sysadmin. Remove permissions to drop tables. If the account is used only for data retrieval, remove all permissions to update data. You might even consider setting up views, locking them down, and using them instead of direct table access.
Turn on ASP.NET Request Validation, described here. This automatically checks all traffic for malicious character sequences.
If possible, consider adding an event handler to Global for OnBeginRequest that inspects the incoming data and performs white list checks on all inputs. Not sure how well this maps to your problem but the nice thing is you only have to do it in once place and it will affect the whole site.
Ensure that all of your pages call Page.Validate to ensure that the client-side validation is also enforced on the server side.
Begin the long hard work of adding field-specific white list validation to every control, and figure out a long term plan to move onto parameterized database calls.
在页面加载期间查找每个页面上的所有文本框控件并禁用特殊按键处理
find all textbox controls on each page during pageload and disable special keys press handling