asp.net利用HttpModule实现防sql注入
程序员文章站
2024-03-09 08:33:11
1、新建一个类,实现ihttpmodule接口 代码 复制代码 代码如下: public class sqlhttpmodule : ihttpmodule { publi...
1、新建一个类,实现ihttpmodule接口
代码
public class sqlhttpmodule : ihttpmodule
{
public void dispose()
{
}
public void init(httpapplication context)
{
context.acquirerequeststate += new eventhandler(context_acquirerequeststate);
}
}
在实现接口的init方法时,我们选择了acquirerequeststate事件,为什么不是begin_request事件呢?这是因为我们在处理的时候可能用的session,而begin_request事件执行的时候还没有加载session状态(关于httpmodule可以参考这一篇)。
2、对网站提交的数据进行处理
(1)、get方式
代码
//url提交数据 get方式
if (context.request.querystring != null)
{
for (int i = 0; i < context.request.querystring.count; i++)
{
key = context.request.querystring.keys[i];
value = context.server.urldecode(context.request.querystring[key]);
if (!filtersql(value))
{
throw new exception("querystring(get) including dangerous sql key word!");
}
}
}
(2)、post方式
代码
//表单提交数据 post方式
if (context.request.form != null)
{
for (int i = 0; i < context.request.form.count; i++)
{
key = context.request.form.keys[i];
if (key == "__viewstate") continue;
value = context.server.htmldecode(context.request.form[i]);
if (!filtersql(value))
{
throw new exception("request.form(post) including dangerous sql key word!");
}
}
}
完整代码:
代码
using system;
using system.collections.generic;
using system.linq;
using system.web;
using system.web.ui;
using system.web.ui.webcontrols;
using system.text;
namespace dotnet.common.webform
{
/// <summary>
/// 简单防止sql注入
/// </summary>
public class sqlhttpmodule : ihttpmodule
{
public void dispose()
{
}
public void init(httpapplication context)
{
context.acquirerequeststate += new eventhandler(context_acquirerequeststate);
}
/// <summary>
/// 处理sql注入
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void context_acquirerequeststate(object sender, eventargs e)
{
httpcontext context = ((httpapplication)sender).context;
try
{
string key = string.empty;
string value = string.empty;
//url提交数据 get方式
if (context.request.querystring != null)
{
for (int i = 0; i < context.request.querystring.count; i++)
{
key = context.request.querystring.keys[i];
value = context.server.urldecode(context.request.querystring[key]);
if (!filtersql(value))
{
throw new exception("querystring(get) including dangerous sql key word!");
}
}
}
//表单提交数据 post方式
if (context.request.form != null)
{
for (int i = 0; i < context.request.form.count; i++)
{
key = context.request.form.keys[i];
if (key == "__viewstate") continue;
value = context.server.htmldecode(context.request.form[i]);
if (!filtersql(value))
{
throw new exception("request.form(post) including dangerous sql key word!");
}
}
}
}
catch (exception ex)
{
throw ex;
}
}
/// <summary>
/// 过滤非法关键字,这个可以按照项目灵活配置
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private bool filtersql(string key)
{
bool flag = true;
try
{
if (!string.isnullorempty(key))
{
//一般配置在公共的文件中,如xml文件,txt文本等等
string sqlstr = "insert |delete |select |update |exec |varchar |drop |creat |declare |truncate |cursor |begin |open|<-- |--> ";
string[] sqlstrarr = sqlstr.split('|');
foreach (string strchild in sqlstrarr)
{
if (key.toupper().indexof(strchild.toupper()) != -1)
{
flag = false;
break;
}
}
}
}
catch
{
flag = false;
}
return flag;
}
}
}
3、在web项目中应用
只要在web.config的httpmodules节点下面添加如下配置即可。
<httpmodules>
<add name="sqlhttpmodule" type="dotnet.common.webform.sqlhttpmodule, dotnet.common.webform"></add>
</httpmodules>
需要说明的是,这个防止sql注入的方法在特定的小项目中还是很简洁高效的,但是不通用,通常我们都是选择参数化(利用orm或者ado.net的参数化)方式防止sql注入。
附:asp.net在网页头部引入js脚本的简单方法
asp.net开发少不了javascript的辅助。在通常项目中,js文件都组织在一个公共目录如js文件夹下。随着项目的深入,你会发现js脚本文件越来越多,公共的脚步库越来越庞大。实际使用的时候,我们通常都是在页面中通过 <script src="..." type="text/javascript" >形式引入js文件,而且引入的越来越多。下面我们就来简单讨论在每个页面引入公共脚本库的统一方式,而不用每个页面都是很多<script src="..." type="text/javascript" >的形式。
和我们以前的做法一样,定义一个页面基类叫basepage,事件和方法如下:
code
using system;
using system.data;
using system.configuration;
using system.collections.generic;
using system.web;
using system.web.security;
using system.web.ui;
using system.web.ui.webcontrols;
using system.web.ui.webcontrols.webparts;
using system.web.ui.htmlcontrols;
using system.reflection;
using system.text;
using system.io;
namespace dotnet.common.webform
{
using dotnet.common.model;
using dotnet.common.util;
public class basepage : system.web.ui.page
{
public basepage()
{
}
protected override void oninit(eventargs e)
{
base.oninit(e);
addheaderjs();//向网页头部添加js等文件
}
#region 网页头添加通用统一js文件
private void addheaderjs()
{
string jspath = "~/js/";
string filepath = server.mappath(jspath);
literal lit = new literal();
stringbuilder sb = new stringbuilder();
if (!directory.exists(filepath))
throw new exception("路径不存在");
list<string> listjs = new list<string>();
foreach (var item in directory.getfiles(filepath, "*.js", searchoption.topdirectoryonly))
{
listjs.add(path.getfilename(item));
}
foreach (var jsname in listjs)
{
sb.append(scriptinclude(jspath + jsname));
}
lit.text = sb.tostring();
header.controls.addat(1, lit);
}
private string resolveheaderurl(string relativeurl)
{
string url = null;
if (string.isnullorempty(relativeurl))
{
url = string.empty;
}
else if (!relativeurl.startswith("~"))
{
url = relativeurl;
}
else
{
var basepath = httpcontext.current.request.applicationpath;
url = basepath + relativeurl.substring(1);
url = url.replace("//", "/");
}
return url;
}
private string scriptinclude(string url)
{
if (string.isnullorempty(url))
throw new exception("路径不存在");
string path = resolveheaderurl(url);
return string.format(@"<script src='{0}' type='text/javascript'></script>", path);
}
#endregion
}
}
这样就简单地解决了引入公共js的问题。同样的原理,你也可以引入其他类型的文件,如css等。
demo下载
代码
复制代码 代码如下:
public class sqlhttpmodule : ihttpmodule
{
public void dispose()
{
}
public void init(httpapplication context)
{
context.acquirerequeststate += new eventhandler(context_acquirerequeststate);
}
}
在实现接口的init方法时,我们选择了acquirerequeststate事件,为什么不是begin_request事件呢?这是因为我们在处理的时候可能用的session,而begin_request事件执行的时候还没有加载session状态(关于httpmodule可以参考这一篇)。
2、对网站提交的数据进行处理
(1)、get方式
代码
复制代码 代码如下:
//url提交数据 get方式
if (context.request.querystring != null)
{
for (int i = 0; i < context.request.querystring.count; i++)
{
key = context.request.querystring.keys[i];
value = context.server.urldecode(context.request.querystring[key]);
if (!filtersql(value))
{
throw new exception("querystring(get) including dangerous sql key word!");
}
}
}
(2)、post方式
代码
复制代码 代码如下:
//表单提交数据 post方式
if (context.request.form != null)
{
for (int i = 0; i < context.request.form.count; i++)
{
key = context.request.form.keys[i];
if (key == "__viewstate") continue;
value = context.server.htmldecode(context.request.form[i]);
if (!filtersql(value))
{
throw new exception("request.form(post) including dangerous sql key word!");
}
}
}
完整代码:
代码
复制代码 代码如下:
using system;
using system.collections.generic;
using system.linq;
using system.web;
using system.web.ui;
using system.web.ui.webcontrols;
using system.text;
namespace dotnet.common.webform
{
/// <summary>
/// 简单防止sql注入
/// </summary>
public class sqlhttpmodule : ihttpmodule
{
public void dispose()
{
}
public void init(httpapplication context)
{
context.acquirerequeststate += new eventhandler(context_acquirerequeststate);
}
/// <summary>
/// 处理sql注入
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void context_acquirerequeststate(object sender, eventargs e)
{
httpcontext context = ((httpapplication)sender).context;
try
{
string key = string.empty;
string value = string.empty;
//url提交数据 get方式
if (context.request.querystring != null)
{
for (int i = 0; i < context.request.querystring.count; i++)
{
key = context.request.querystring.keys[i];
value = context.server.urldecode(context.request.querystring[key]);
if (!filtersql(value))
{
throw new exception("querystring(get) including dangerous sql key word!");
}
}
}
//表单提交数据 post方式
if (context.request.form != null)
{
for (int i = 0; i < context.request.form.count; i++)
{
key = context.request.form.keys[i];
if (key == "__viewstate") continue;
value = context.server.htmldecode(context.request.form[i]);
if (!filtersql(value))
{
throw new exception("request.form(post) including dangerous sql key word!");
}
}
}
}
catch (exception ex)
{
throw ex;
}
}
/// <summary>
/// 过滤非法关键字,这个可以按照项目灵活配置
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private bool filtersql(string key)
{
bool flag = true;
try
{
if (!string.isnullorempty(key))
{
//一般配置在公共的文件中,如xml文件,txt文本等等
string sqlstr = "insert |delete |select |update |exec |varchar |drop |creat |declare |truncate |cursor |begin |open|<-- |--> ";
string[] sqlstrarr = sqlstr.split('|');
foreach (string strchild in sqlstrarr)
{
if (key.toupper().indexof(strchild.toupper()) != -1)
{
flag = false;
break;
}
}
}
}
catch
{
flag = false;
}
return flag;
}
}
}
3、在web项目中应用
只要在web.config的httpmodules节点下面添加如下配置即可。
<httpmodules>
<add name="sqlhttpmodule" type="dotnet.common.webform.sqlhttpmodule, dotnet.common.webform"></add>
</httpmodules>
需要说明的是,这个防止sql注入的方法在特定的小项目中还是很简洁高效的,但是不通用,通常我们都是选择参数化(利用orm或者ado.net的参数化)方式防止sql注入。
附:asp.net在网页头部引入js脚本的简单方法
asp.net开发少不了javascript的辅助。在通常项目中,js文件都组织在一个公共目录如js文件夹下。随着项目的深入,你会发现js脚本文件越来越多,公共的脚步库越来越庞大。实际使用的时候,我们通常都是在页面中通过 <script src="..." type="text/javascript" >形式引入js文件,而且引入的越来越多。下面我们就来简单讨论在每个页面引入公共脚本库的统一方式,而不用每个页面都是很多<script src="..." type="text/javascript" >的形式。
和我们以前的做法一样,定义一个页面基类叫basepage,事件和方法如下:
code
复制代码 代码如下:
using system;
using system.data;
using system.configuration;
using system.collections.generic;
using system.web;
using system.web.security;
using system.web.ui;
using system.web.ui.webcontrols;
using system.web.ui.webcontrols.webparts;
using system.web.ui.htmlcontrols;
using system.reflection;
using system.text;
using system.io;
namespace dotnet.common.webform
{
using dotnet.common.model;
using dotnet.common.util;
public class basepage : system.web.ui.page
{
public basepage()
{
}
protected override void oninit(eventargs e)
{
base.oninit(e);
addheaderjs();//向网页头部添加js等文件
}
#region 网页头添加通用统一js文件
private void addheaderjs()
{
string jspath = "~/js/";
string filepath = server.mappath(jspath);
literal lit = new literal();
stringbuilder sb = new stringbuilder();
if (!directory.exists(filepath))
throw new exception("路径不存在");
list<string> listjs = new list<string>();
foreach (var item in directory.getfiles(filepath, "*.js", searchoption.topdirectoryonly))
{
listjs.add(path.getfilename(item));
}
foreach (var jsname in listjs)
{
sb.append(scriptinclude(jspath + jsname));
}
lit.text = sb.tostring();
header.controls.addat(1, lit);
}
private string resolveheaderurl(string relativeurl)
{
string url = null;
if (string.isnullorempty(relativeurl))
{
url = string.empty;
}
else if (!relativeurl.startswith("~"))
{
url = relativeurl;
}
else
{
var basepath = httpcontext.current.request.applicationpath;
url = basepath + relativeurl.substring(1);
url = url.replace("//", "/");
}
return url;
}
private string scriptinclude(string url)
{
if (string.isnullorempty(url))
throw new exception("路径不存在");
string path = resolveheaderurl(url);
return string.format(@"<script src='{0}' type='text/javascript'></script>", path);
}
#endregion
}
}
这样就简单地解决了引入公共js的问题。同样的原理,你也可以引入其他类型的文件,如css等。
demo下载
上一篇: 全方位讲解Java的面向对象编程思想
下一篇: Java读取txt文件的方法