防护针对SQL Server数据库的SQL注入攻击
SQL注入可能是最常见的攻击面向Internet的SQL Server数据库的方法。即使你对网络和防火墙进行了防护,只要应用程序存在漏洞,那么依然存在受攻击的可能。微软已经注意到最近针对使用ASP和ASP.NET网站的攻击数量呈上升趋势。这不仅会导致数据的失窃和丢失,在近期的很多案例中数据库中还被攻击者加入恶意javascript代码,这导致访问网站的客户电脑也会因此感染病毒。
防护针对您数据库的SQL注入攻击有如下的几种方法:
1. 使用双引号
使用双引号或其他符号替换您的用户的输入值。这种简单的预防措施能较为有效的防护相当多的SQL注入攻击。单引号经常被用于结束SQL表达式,使输入的内容获得不必要的权限。
代码如下:
string strSanitizedInput = strInput.Replace("'", "''");
注意:请记住即使你已经替换了单引号,攻击者也有可能绕过这个防护措施。
2. 避免动态SQL
动态SQL是动态查询的很好的工具,但这也会暴露脆弱点。很多情况下可以使用其他SQL语句或存储过程来代替动态SQL。当然,如果您在存储过程中依然通过用户输入来建立动态SQL查询,那么只靠替换还是不安全的。
较好的使用参数的SQL语句如下:
private void cmdLogin_Click(object sender, System.EventArgs e) {
string strcode = ConfigurationSettings.AppSettings["CodeBad"];
using (SqlConnection code = new SqlConnection(strcode))
{
SqlParameter prm;
code.Open();
string strQry =
"SELECT Count(*) FROM Users WHERE UserName=@username " +
"AND Password=@password";
int intRecs;
SqlCommand cmd = new SqlCommand(strQry,code);
cmd.CommandType= CommandType.Text;
prm = new SqlParameter("@username",SqlDbType.VarChar,50);
prm.Direction=ParameterDirection.Input;
prm.Value = txtUser.Text;
cmd.Parameters.Add(prm);
prm = new SqlParameter("@password",SqlDbType.VarChar,50);
prm.Direction=ParameterDirection.Input;
prm.Value = txtPassword.Text;
cmd.Parameters.Add(prm);
intRecs = (int) cmd.ExecuteScalar();
if (intRecs>0) {
FormsAuthentication.RedirectFromLoginPage(txtUser.Text, false);
}
else {
lblMsg.Text = "Login attempt failed.";
}
}
}
使用procVerifyUser存储过程来验证用户是一种更好的方法:
private void cmdLogin_Click(object sender, System.EventArgs e) {
string strcode =
ConfigurationSettings.AppSettings["CodeBetter"];
using (SqlConnection code = new SqlConnection(strcode))
{
SqlParameter prm;
code.Open();
string strAccessLevel;
SqlCommand cmd = new SqlCommand("procVerifyUser", code);
cmd.CommandType= CommandType.StoredProcedure;
prm = new SqlParameter("@username",SqlDbType.VarChar,50);
prm.Direction=ParameterDirection.Input;
prm.Value = txtUser.Text;
cmd.Parameters.Add(prm);
prm = new SqlParameter("@password",SqlDbType.VarChar,50);
prm.Direction=ParameterDirection.Input;
prm.Value = txtPassword.Text;
cmd.Parameters.Add(prm);
strAccessLevel = (string) cmd.ExecuteScalar();
if (strAccessLevel.Length>0) {
FormsAuthentication.RedirectFromLoginPage(txtUser.Text, false);
}
else {
lblMsg.Text = "Login attempt failed.";
}
}
}
3. 验证所有的输入
永远不要信任用户的输入。
如果输入域中只能包含数字,那就需要验证用户输入的值是否只包含数字。如果允许输入字符,那么就需要检查是否有允许范围之外的字符。您的应用程序应该包含对诸如分号,等号,冒号,括号和SQL关键字的检查。.NET Framework提供常用的输入检查表达式来简化这个过程。限制用户输入的长度也是一种很好的方法。
您可以使用下列代码来检查输入值限于4-12位的数字,字母和下划线:
[\d_a-zA-Z]{4,12}
4. 最低权限原则
永远也不要在代码中用管理员级别权限的帐户来连接数据库。
应用程序使用的帐户应该只拥有应用程序需要的最低级别的权限。这也能将已入侵者造成的破坏降低到最低限度。应用程序不能已sa或其他管理员帐号连接数据库,而且应定义使用的帐号能访问的范围。
错误的使用系统管理员权限的代码如下:
<add key="CodeBad"
value="server=localhost;uid=sa;pwd=;database=northwind;" />
有限制的正确代码如下:
<add key="CodeGood"
value="server=localhost;uid=NWindReader;pwd=utbbeesozg4d;
database=northwind;" />
5. 安全存储机密信息
不要用明文存储机密信息。
较好的替代方法是使用加密或散列密码。散列密码较加密密码更安全,这是因为它们不能被解密。你还可以在散列加密之前添加一些随机值来增加安全性。
好的代码如下:
private void cmdLogin_Click(object sender, System.EventArgs e) {
try {
// Grab the encrypted connection string and decrypt it
string strcode = SecureConnection.GetcodeString("CodeBest");
// Establish connection to database
using (SqlConnection code = new SqlConnection(strcode))
{
SqlParameter prm;
code.Open();
// Execute sproc to retrieved hashed password for this user
string strHashedDbPwd;
SqlCommand cmd = new SqlCommand("procGetHashedPassword", code);
cmd.CommandType = CommandType.StoredProcedure;
prm = new SqlParameter("@username", SqlDbType.VarChar,50);
prm.Direction = ParameterDirection.Input;
prm.Value = txtUser.Text;
cmd.Parameters.Add(prm);
strHashedDbPwd = (string) cmd.ExecuteScalar();
if (strHashedDbPwd.Length>0) {
// Verify that hashed user-entered password is the same
// as the hashed password from the database
if (SaltedHash.ValidatePassword(txtPassword.Text,
strHashedDbPwd)) {
FormsAuthentication.RedirectFromLoginPage(
txtUser.Text, false);
}
else {
lblMsg.Text = "Login attempt failed.";
}
}
else {
lblMsg.Text = "Login attempt failed.";
}
}
}
catch {
lblMsg.Text = "Login attempt failed.";
}
}
加密的连接字符串在Web.Config中存储如下:
<add key="CodeBest"
value="AQAAANCMnd8BFdERjHoAwE/
Cl+sBAAAAcWMZ8XhPz0O8jHcS1539LAQAAAACAAAAAAADZgAAqAAAABAAAABdodw0YhWfcC6+
UjUUOiMwAAAAAASAAACgAAAAEAAAALPzjTRnAPt7/W8v38ikHL5IAAAAzctRyEcHxWkzxeqbq/
V9ogaSqS4UxvKC9zmrXUoJ9mwrNZ/
XZ9LgbfcDXIIAXm2DLRCGRHMtrZrp9yledz0n9kgP3b3s+
X8wFAAAANmLu0UfOJdTc4WjlQQgmZElY7Z8"
/>
6. 适当地处理异常
在您所有的代码中加入异常处理,而且所有的异常应该提供最少量的信息。
对于没有处理的异常,应该确保不能使攻击者获得有用的信息。可以通过设置Web.Config中的debug选项和设置CustomError的模式为"RemoteOnly"。
范例:
<compilation defaultLanguage="c#"
debug="false"
/>
<customErrors mode="RemoteOnly"
/>
辅助工具:
微软也为管理员提供了几个辅助工具,用于检测,防护和识别可能的脆弱点。
检测 - HP Scrawlr
http://www.communities.hp.com/securitysoftware/blogs/spilabs/archive/2008/06/23/finding-sql-injection-with-scrawlr.aspx
防护 – UrlScan 3.0版 Beta
http://learn.iis.net/page.aspx/473/using-urlscan
识别 – Microsoft Source Code Analyzer for SQL Injection
http://support.microsoft.com/kb/954476
更详细的SQL Server最优防护实践信息可参考:
"SQL Server 2005 Security Best Practices - Operational and Administrative Tasks"
http://www.microsoft.com/technet/prodtechnol/sql/2005/sql2005secbestpract.mspx
"How To - Protect from Injection Attacks in ASP.NET"
http://msdn.microsoft.com/en-us/library/bb355989.aspx
"How To - Protect from SQL Injection in ASP.NET"
http://msdn.microsoft.com/en-us/library/ms998271.aspx
"How To - Protect from Cross-Site Scripting in ASP.NET"
http://msdn.microsoft.com/en-us/library/ms998274.aspx
"Design Guidelines"
http://msdn.microsoft.com/en-us/library/aa302420.aspx
"Arch/Design Inspection"
http://msdn.microsoft.com/en-us/library/aa302421.aspx
"Microsoft Security Advisory"
http://www.microsoft.com/technet/security/advisory/954462.mspx
转载于:https://www.cnblogs.com/galaxyyao/archive/2009/02/28/1400419.html
防护针对SQL Server数据库的SQL注入攻击相关推荐
- 将excel数据导入到SQL server数据库,SQL server引入导入excel报表,如何解决“未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序”问题
目录 版本: 文章主要内容: 未在本地计算机上注册"Microsoft.ACE.OLEDB.12.0"提供程序 新版本不同的设置的地方: 版本: SQL server2018.ex ...
- SQL Server 数据库之SQL Server 数据库的安全设置
SQL Server 数据库的安全设置 1. 概述 2. 更改登录用户验证方式 3. 创建与删除登录用户 4. 创建与删除数据库用户 5. 设置服务器角色权限 5.1. **查看角色属性** 5.2 ...
- SQL SERVER 数据库实用SQL语句
--查看指定表的外键约束 select * from sysobjects where parent_obj in( select id from sysobjects where name='表名' ...
- MS SQL Server 数据库分离-SQL语句
前言 今天在在清理数据库,是MS SQL Server,其中用到分离数据库文件.在这过程中,出现了一个小小的问题:误将数据库日志文件删除了,然后数据就打不开了,除了脱机,其他操作都报错. 数据库分离 ...
- SqlPackage.exe –使用bacpac和PowerShell或Batch技术自动执行SQL Server数据库还原
Data is the key to your organization's future, but if it's outdated, irrelevant, or hidden then it's ...
- [转载]在SQL Server数据库之间进行数据导入导出,OPENDATASOURCE
需要在c盘下先建立一个data.txt文件,然后在文件的第一行写上你要导出的列,不如说要导出id和name这两列,就在第一行写上 id,name 然后保存,使用下列SQL就可以了,你如果要保持原有的I ...
- 【转载】在C#中运用SQLDMO备份和恢复Microsoft SQL Server数据库
在C#中运用SQLDMO备份和恢复Microsoft SQL Server数据库 SQLDMO(SQL Distributed Management Objects,SQL分布式管理对象)封装了Mic ...
- 在SQL Server数据库之间进行数据导入导出
来源:http://kb.cnblogs.com/page/94464/ 在SQL Server数据库之间进行数据导入导出 (1).使用SELECT INTO导出数据 在SQL Server中使用最广 ...
- 如何对两个大型SQL Server数据库中的数据进行快速估计比较,以查看它们是否相等
Bringing impactful analysis into a data always comes with challenges. In many cases, we rely on auto ...
- 了解SQL Server数据库恢复模型
A recovery model is a database configuration option that determines the type of backup that one coul ...
最新文章
- HTML中的form表单有一个关键属性 enctype
- js 页面跳转保存状态
- Android适配全面总结(二)
- linux怎么安装高德导航软件,高德地图车机版如何安装?高德地图车机版安装教程...
- SQLServer2008 查询分析器内容未保存,查找分析器内容
- 在线文本转2-36任意进制工具
- 从GitHub火到了CSDN,共计1658页的《Java岗面试核心MCA版》
- Excel/WPS做数据透视表,即对变量做交叉汇总(列联表)
- 跳舞的小人 和 盲文
- gpuz怎么看显存颗粒
- python 制作正态分布图,画出拒绝域
- 高德地图 去掉左下角logo
- 用python实现淘宝毫秒级秒!! 天猫淘宝的抢购完美实现 而且说实话有很多人需要它。 每次在抢购前的无法提交订单导致很多买家无法购买。 今天我教给大家如何更好快速实现你的购买愿望! 教程如下!请仔
- Amazon vs Google 云服务
- JavaSE(二)-抽象类
- CSS 添加背景图片
- 快递100 home.html代码
- 和大于等于target的最短子数组 | 循序递进---@二十一画
- 基于管道过滤器实现的kwic实现
- 迅雷自媒体,看片神器迅雷也推出公众号了