Webセキュリティの小部屋

Twitter のフォローはこちらから Facebook ページはこちら RSSフィードのご登録はこちらから
公開日:2013年3月3日
最終更新日:2020年8月15日

SQLインジェクション対策(ASP.NET,C#,VB.NET編)

概要

SQL インジェクションの対策は、簡単に言えば SQL で静的プレースホルダを使用することです。

静的プレースホルダの詳細については、以下の記事を参照してください。

では、ASP.NET(C#, VB.NET) で SQL インジェクション対策を実際にどのように行うのか簡単なログイン処理で具体的に見てみましょう。

ログイン処理の概要は以下の通りです。動作環境は、.NET Framework 4.5 + SQL Server 2012 になります。

login

接続先のデータベース名は Test、テーブル名は LOGIN で、列名は ID, PASSWORD です。

.NET でデータベースにアクセスする方法は、LINQ を使用する方法と、DataReader を使用する方法があります。LINQ は使用するだけで SQL インジェクションの脆弱性を回避できるので、今後は LINQ を使用することを推奨します(参考1(Entitiy Framework),参考2(LINQ to SQL))。

なお、これは簡単なログイン処理のため、ログインにまつわるセキュリティ対策は省いています。ログインのセキュリティ対策は、以下の記事を参照してください。

LINQ を使用したログイン処理

LINQ は Entitity Framework で LINQ to Entities を使用します。事前に、エンティティの定義を作成しておく必要があります。

・Login.aspx(C#)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;

namespace TestCS
{
  public partial class Login : System.Web.UI.Page
  {
    protected void ButtonLogin_Click(object sender, EventArgs e)
    {
      //パラメーター取得
      string id = this.TextBoxID.Text;
      string passwword = this.TextBoxPassword.Text;

      //インスタンス作成
      var entities = new LoginEntities();

      //クエリ作成
      var query = from t in entities.LOGIN
            where t.ID == id && t.PASSWORD == passwword
            select t;
      

      //ログイン処理&ログイン成功
      if (query.Count() == 1)
      {
        //セッションに値格納
        Session["id"] = id;

        //リダイレクト
        Response.Redirect("Welcome.aspx");
      }
    }
  }
}

・Login.aspx(VB.NET)

Public Class Login1
  Inherits System.Web.UI.Page

  Protected Sub ButtonLogin_Click(sender As Object, e As EventArgs) Handles ButtonLogin.Click
    'パラメーター取得'
    Dim id As String = Me.TextBoxID.Text
    Dim password As String = Me.TextBoxPassword.Text

    'インスタンス作成'
    Dim entities = New LoginEntities()

    'クエリ作成'
    Dim query = From t In entities.LOGIN _
          Where t.ID = id And t.PASSWORD = password _
          Select t

    If query.Count = 1 Then
      'セッションに値格納'
      Session("id") = id

      'リダイレクト'
      Response.Redirect("Welcome.aspx")
    End If

  End Sub
End Class

DataReader を使用したログイン処理

・Login.aspx(C#)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;

namespace TestCS
{
  public partial class Login : System.Web.UI.Page
  {
    protected void ButtonLogin_Click(object sender, EventArgs e)
    {
      int count = 0;

      //接続文字列
      string connectionString = @"Server=(local)\SQLEXPRESS;Initial Catalog=Test;User ID=user01;Password=pass";

      //接続作成
      SqlConnection con = new SqlConnection(connectionString);

      //プレースホルダで SQL 作成
      string sql = "SELECT COUNT(*) AS CNT FROM LOGIN WHERE ID = @ID AND PASSWORD = @PASSWORD;";

      //パラメーター取得
      string id = this.TextBoxID.Text;
      string passwword = this.TextBoxPassword.Text;

      //プレースホルダにパラメーター設定
      SqlCommand command = new SqlCommand(sql, con);
      SqlParameter pID = new SqlParameter("@ID", id);
      command.Parameters.Add(pID);

      SqlParameter pPassword = new SqlParameter("@PASSWORD", passwword);
      command.Parameters.Add(pPassword);

      //接続オープン
      con.Open();

      //SQL 実行
      SqlDataReader reader = command.ExecuteReader();

      if (reader.HasRows)
      {
        while (reader.Read())
        {
          count = (int)reader["CNT"];
        }
      }

      reader.Close();
      con.Close();

      if (count == 1)
      {
        //ログイン成功
        Session["id"] = id;
        Server.Transfer("Welcome.aspx");
      }
    }
  }
}

・Login.aspx(VB.NET)
Imports System.Data.SqlClient

Public Class Login1
  Inherits System.Web.UI.Page

  Protected Sub ButtonLogin_Click(sender As Object, e As EventArgs) Handles ButtonLogin.Click
    Dim count As Integer = 0

    '接続文字列'
    Dim connectionString As String = "Server=(local)\SQLEXPRESS;Initial Catalog=Test;User ID=user01;Password=pass"

    '接続作成'
    Dim con As SqlConnection = New SqlConnection(connectionString)

    'プレースホルダで SQL 作成'
    Dim sql As String = "SELECT COUNT(*) AS CNT FROM LOGIN WHERE ID = @ID AND PASSWORD = @PASSWORD;"

    'パラメーター取得'
    Dim id As String = Me.TextBoxID.Text
    Dim password As String = Me.TextBoxPassword.Text

    'プレースホルダにパラメーター設定'
    Dim command As SqlCommand = New SqlCommand(sql, con)
    Dim pID As SqlParameter = New SqlParameter("@ID", id)
    command.Parameters.Add(pID)

    Dim pPassword As SqlParameter = New SqlParameter("@PASSWORD", password)
    command.Parameters.Add(pPassword)

    '接続オープン'
    con.Open()

    'SQL 実行'
    Dim reader As SqlDataReader = command.ExecuteReader()

    If reader.HasRows Then
      While reader.Read()
        count = CType(reader("CNT"), Integer)
      End While
    End If

    reader.Close()
    con.Close()

    If count = 1 Then
      'ログイン成功'
      Session("id") = id
      Server.Transfer("Welcome.aspx")
    End If

  End Sub
End Class

Welcome 画面

・Welcome.aspx(C#)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace TestCS
{
  public partial class Welcome : System.Web.UI.Page
  {
    protected void Page_Load(object sender, EventArgs e)
    {
      //IDを表示
      this.LabelID.Text = HttpUtility.HtmlEncode((string)Session["id"]);
    }
  }
}

・Welcome.aspx(VB.NET)
Public Class Welcome
  Inherits System.Web.UI.Page

  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    'IDを表示'
    Me.LabelID.Text = HttpUtility.HtmlEncode(CType(Session("id"), String))
  End Sub

End Class

参考

Webアプリケーションセキュリティに関する記事は、以下のページにまとまっています。ぜひご確認ください。


スポンサーリンク





カテゴリー:Webアプリケーションセキュリティ対策

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA