asp.Net HttpModuleによるsql注入防止

8358 ワード

1、新しいクラスを作り、IHttpModuleインタフェースを実現する
コード#コード#
 
  
public class SqlHttpModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.AcquireRequestState += new EventHandler(context_AcquireRequestState);
}
}

インタフェースのInitメソッドを実装する際、AcquireRequestStateイベントを選択しました.なぜBegin_ではないのですか.Requestイベントは?これは私たちが処理するときに使用する可能性のあるセッションのためで、Begin_Requestイベント実行時にセッションステータスがロードされていません(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
{
///
/// sql
///

public class SqlHttpModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.AcquireRequestState += new EventHandler(context_AcquireRequestState);
}
///
/// sql
///

///
///
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;
}
}
///
/// ,
///

///
///
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ノードの下に以下の構成を追加すればよい.
なお、このsql注入防止方法は、特定の小項目においても簡潔で効率的であるが、汎用的ではなく、通常、パラメータ化(ormまたはado.netのパラメータ化を利用する)方式を選択してsql注入を防止する.
附:asp.Netページヘッダにjsスクリプトを導入する簡単な方法
asp.Net開発にはJavaScriptの支援が欠かせない.通常のプロジェクトでは、jsファイルはjsフォルダなどの共通ディレクトリに整理されます.プロジェクトが進むにつれて、jsスクリプトファイルがますます多くなり、共通の足取りライブラリがますます膨大になっていることがわかります.実際に使用する場合、jsファイルをページに形式的に導入し、導入することが多くなります.次に、各ページに共通スクリプトライブラリを導入する統一方法について簡単に説明します.各ページが多くなくても<script src="..."type="text/javascript">で行ないます.
<br>以前の方法と同様に、BasePageというページベースクラスを定義します.イベントと方法は次のとおりです.
<br>Code
<br>
<div class="codetitle">
<span><u></u></span> コードは次のとおりです.
</div>
<div class="codebody"id="code26122">
<br>using System;
<br>using System.Data;
<br>using System.Configuration;
<br>using System.Collections.Generic;
<br>using System.Web;
<br>using System.Web.Security;
<br>using System.Web.UI;
<br>using System.Web.UI.WebControls;
<br>using System.Web.UI.WebControls.WebParts;
<br>using System.Web.UI.HtmlControls;
<br>using System.Reflection;
<br>using System.Text;
<br>using System.IO;
<br>namespace DotNet.Common.WebForm
<br>{
<br>using DotNet.Common.Model;
<br>using DotNet.Common.Util;
<br>public class BasePage : System.Web.UI.Page
<br>{
<br>public BasePage()
<br>{
<br>}
<br>protected override void OnInit(EventArgs e)
<br>{
<br>base.OnInit(e);
<br>AddHeaderJs();//ページヘッダにjsなどのファイルを追加
<br>}
<br>#regionページヘッダ汎用統合jsファイルの追加
<br>private void AddHeaderJs()
<br>{
<br>string jsPath = "~/js/";
<br>string filePath = Server.MapPath(jsPath);
<br>Literal lit = new Literal();
<br>StringBuilder sb = new StringBuilder();
<br>if (!Directory.Exists(filePath))
<br>throw new Exception(「パスが存在しない」);
<br>List<string> listJs = new List<string>();
<br>foreach (var item in Directory.GetFiles(filePath, "*.js", SearchOption.TopDirectoryOnly))
<br>{
<br>listJs.Add(Path.GetFileName(item));
<br>}
<br>foreach (var jsname in listJs)
<br>{
<br>sb.Append(ScriptInclude(jsPath + jsname));
<br>}
<br>lit.Text = sb.ToString();
<br>Header.Controls.AddAt(1, lit);
<br>}
<br>private string ResolveHeaderUrl(string relativeUrl)
<br>{
<br>string url = null;
<br>if (string.IsNullOrEmpty(relativeUrl))
<br>{
<br>url = string.Empty;
<br>}
<br>else if (!relativeUrl.StartsWith("~"))
<br>{
<br>url = relativeUrl;
<br>}
<br>else
<br>{
<br>var basePath = HttpContext.Current.Request.ApplicationPath;
<br>url = basePath + relativeUrl.Substring(1);
<br>url = url.Replace("//", "/");
<br>}
<br>return url;
<br>}
<br>private string ScriptInclude(string url)
<br>{
<br>if (string.IsNullOrEmpty(url))
<br>throw new Exception(「パスが存在しない」);
<br>string path = ResolveHeaderUrl(url);
<br>return string.Format(@"<script src='{0}' type='text/javascript'>", path);
}
#endregion
}
}
これにより,共通jsの導入の問題を簡単に解決した.同じ原理で、cssなどの他のタイプのファイルを導入することもできます.
demoダウンロード