c# - 在 C# 中防止 SQL 注入(inject) asp.net

标签 c# asp.net sql sql-injection

<分区>

我一直在尝试修复这个 SQL 注入(inject)站点,但我一直在处理的一个页面让我停止了 2 天。

到目前为止,我正在验证来自客户端站点的用户输入。正则表达式验证器。

在此页面上,这是用户唯一输入的内容。还有一个动态下拉列表正在使用服务器端验证进行验证。

来自用户名文本框的数据也在客户端使用 Regex 进行验证。

最初我将所有查询都转换为参数化查询。由于我已将所有参数化查询转换为存储过程。

现在我不知道下一步该去哪里。通过搜索论坛,客户端验证和参数化查询的组合通常可以防止注入(inject)。

我觉得我在这里遗漏了一些东西。

附件是页面的代码以及c#中的用户控件。任何方向将不胜感激!

#
  <%@ Control Language="C#" AutoEventWireup="true"    Inherits="EPayment.AdminSite.AssignUsersUC"   %>

<script runat="server" type="text/javascript" >
</script>

<div style="float:left;width:120px"><asp:Label ID="UserNameLbl" runat="server" Text="User Logon:" CssClass="label"></asp:Label></div>
<div style="float:left; height: 22px;"><asp:TextBox ID="UserNameTxt" runat="server"  OnTextChanged="UserNameTxt_TextChanged"></asp:TextBox>

 <asp:RegularExpressionValidator id="RegularExpressionValidator1" 
                     ControlToValidate="userNameTxt"
                     ValidationExpression="[a-zA-Zs0-9]{1,40}$"
                     AutoPostBack="true"
                     Display="Static"
                     ErrorMessage="Username must contain only Alpha-Numeric Characters"
                     EnableClientScript="False" 
                     runat="server"/>


  <div style="float:left">  <asp:DropDownList ID="ddlcompany" runat="server" AutoPostBack="true" DataTextField="CompanyName" DataValueField="CompanyId" OnSelectedIndexChanged="ddlcompany_SelectedIndexChanged" >

  </asp:DropDownList></div>

   </div>
   <br />
  <div style="clear:both"><asp:Label ID="companyLbl" runat="server" Text="Company:" CssClass="label"></asp:Label>  </div>

   <br />
   <div> <asp:Button ID="btngetroles" Text="GetRoles" runat="server" Visible="false" OnClick="btngetroles_Click" /><asp:Button ID="btngetuserobject" Text="GetUserId" runat="server" Visible="false" OnClick="btngetuserobject_Click"  /></div>
<div class="sectionRow" style="width:100%;">Roles:
</div>

<br />

 <div style="width:600px">
 <asp:GridView ID="GV" runat="server" DataKeyNames="RoleId" AutoGenerateColumns="false" Width="100%" ShowHeader="true" ShowFooter="false" 
 PageSize="100" CellPadding="7">
     <HeaderStyle CssClass="gridHdr" />
 <Columns>

  <asp:TemplateField>
 <ItemTemplate>
 <asp:CheckBox id="CheckBox2" runat="server" AutoPostBack="True" ></asp:CheckBox>


 </ItemTemplate>

 </asp:TemplateField>

 <asp:TemplateField HeaderText="Role Description" >
<ItemTemplate >
<%#
                    DataBinder.Eval(Container.DataItem, "RoleDesc").ToString().Trim()
                %>

</ItemTemplate>



</asp:TemplateField>


 </Columns>


 </asp:GridView>



 </div>
<br />
 <div style="float:left;width:120px"><asp:Button ID="btnSave" runat="server" Text="Save" OnClick="btnSave_Click"   />
 <asp:Button ID="btnReset" runat="server" Text="Reset" OnClick="btnReset_Click"   />
 </div>
 <div>
 <asp:Label ID="Result" runat="server" ForeColor="red"></asp:Label></div>
#
using System;
using System.Data;
using System.Configuration;
using System.Collections;
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 EPayment.DatabaseConnectors;
using EPayment.DataObjects;
using EPayment.Common;
using ESource.Security;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using ESource.Installation;

namespace EPayment.AdminSite
{
    public partial class AssignUsersUC : System.Web.UI.UserControl
    {
        private string ConnectionString;
        protected SYUserConnector syuserconnector;
        protected SYTaskConnector sytaskconnector;
        protected SYRoleConnector syroleconnector;
        protected SYTask sytask;
        protected SYUser syuser;
        protected SYRole syrole;
        protected SYUtility syutility;
        private DBConnString dbconn;
        private string dbFilePath;
        private string logFilePath;
        protected TextBox UserNameTxt;
        protected DropDownList ddlcompany;
        protected GridView GV;
        //protected TextBox UserIdtxt;
        protected Label Result;

        private MerchantDBConnector mConnector;
        private InstallationManager dbReg;


        protected void Page_Load(object sender, EventArgs e)
        {

            UserNameTxt.AutoPostBack = true;

            syuserconnector = new SYUserConnector();
            syuserconnector.SetConnection(ConnectionString);
            syroleconnector = new SYRoleConnector();
            syroleconnector.SetConnection(ConnectionString);

            sytaskconnector = new SYTaskConnector();
            sytaskconnector.SetConnection(ConnectionString);

            syutility = new SYUtility();
            syutility.SetConnection(ConnectionString);
            syuser = new SYUser();


            if (!IsPostBack)
            {
                DataTable dt = new DataTable();
                dt = syutility.GetSYCompanies();
                ddlcompany.DataSource = dt;
                ddlcompany.DataBind();

                ArrayList companies = mConnector.GetGPCompanyIds();
                foreach (string[] company in companies)
                {
                    ddlcompany.SelectedIndex = -1;
                    ddlcompany.Items.FindByText(company[1]);
                    //Context.Response.Write(ddlcompany.SelectedItem.Text + "<br>");
                    //Context.Response.Write("Before:" + company[1] + "<br>");
                    //Context.Response.Write("Before Company ID:" + company[0] + "<br>");

                    if (ddlcompany.SelectedItem.Text.Trim() == company[1].Trim())
                    {
                        //Context.Response.Write("if:" + ddlcompany.SelectedItem.Text.Trim() + "<br>");
                        //Context.Response.Write("Company Name:" + company[1] + "<br>");
                        //Context.Response.Write("Company ID:" + company[0] + "<br>");
                    }
                    else
                    {

                        //Context.Response.Write("else:" + ddlcompany.SelectedItem.Text.Trim() + "<br>");
                        //Context.Response.Write("Company ID:" + company[0] + "<br>");
                        DBConnString epConn = new DBConnString(logFilePath, dbFilePath);

                        dbReg.InsertGPCompanyIntoSYCompany(epConn.StrGPServer, epConn.StrGPUser, epConn.StrGPPass, ConfigurationManager.AppSettings["EPaymentDBName"], company[0], company[1]);

                        //ddlcompany.Items.Add(new ListItem(company[1], company[0]));
                        dt = syutility.GetSYCompanies();
                        ddlcompany.Items.Clear();
                        ddlcompany.DataSource = dt;
                        ddlcompany.DataBind();
                    }
                }


                //ddlcompany.Items.Insert(0, new ListItem("ViewAll", "ViewAll"));
                string companyname = ConfigurationManager.AppSettings["EPaymentCompanyERPId"];
                string companyID = syutility.GetCompanyId(companyname);
                DataView dv = new DataView();
                dv = syroleconnector.GetAllRoles(companyID, 0);
                GV.DataSource = dv;
                GV.DataBind();
            }


        }
        protected void btngetroles_Click(object sender, EventArgs e)
        {

        }
        protected void ddlcompany_SelectedIndexChanged(object sender, EventArgs e)
        {
            Getroles();

        }
        protected void Page_UnLoad(object sender, EventArgs e)
        {
            syuserconnector.CloseConnection();
            syroleconnector.CloseConnection();
            sytaskconnector.CloseConnection();
            syutility.CloseConnection();
            syuserconnector = null;
            syroleconnector = null;
            sytaskconnector = null;
            syutility = null;
            syuser = null;

        }
        private void Page_Init(System.Object sender, System.EventArgs e) //Handles page_init event
        {
            string serverPath = Request.PhysicalApplicationPath;
            dbFilePath = serverPath + "include\\dbconn.txt";
            logFilePath = serverPath + "logs\\azoxlog.txt";
            dbconn = new DBConnString(logFilePath, dbFilePath);
            ConnectionString = dbconn.StrEPConnString;

            MerchantAccount m = new MerchantAccount();
            mConnector = new MerchantDBConnector(dbFilePath, logFilePath, m);

            dbReg = new InstallationManager();
            dbReg.UseLogFile = true;
            dbReg.LogFilePath = logFilePath;

        }
        protected void btnSave_Click(object sender, EventArgs e)
        {
            if (Page.IsValid)
            {
                syuser = new SYUser();
                //Regex r = new Regex("^[a-zA-Z0-9]*$");
                //if (r.IsMatch(UserNameTxt.Text.Trim()))
                //{
                string username = UserNameTxt.Text;
                string companyID = ddlcompany.SelectedItem.Value;
                ArrayList companies = mConnector.GetGPCompanyIds();
                //bool found = companies.Contains(companyID);
                //if (found == true)
                //{
                    string userid = syuserconnector.GetUserId(username, companyID);

                    if (userid != null && userid != "")
                    {

                        Result.Text = "";

                        //string userId = UserIdtxt.Text;
                        Collection<string> idsList = new Collection<string>();
                        foreach (GridViewRow row in GV.Rows)
                        {
                            CheckBox chk = (CheckBox)row.FindControl("CheckBox2");
                            if (chk != null && chk.Checked)
                            {
                                string secId = GV.DataKeys[row.RowIndex].Value.ToString();

                                idsList.Add(secId);

                                //Response.Write("TaskId: " +secId + "<br/>");
                                //Response.End();
                            }

                        }
                        syuserconnector.UpdateUserRoles(userid, idsList);
                        //Start Check if user is given access to BatchProcess and add user to ep database so that sql user has access to EP_BatchReport table which is public
                        UserDBConnector userConn = new UserDBConnector(dbFilePath, logFilePath, new EPayment.DataObjects.User());
                        userConn.CreateUserLogOnForBatchReportAccess(UserNameTxt.Text);
                        //End
                        Result.Text = "Roles are Assigned to the User";


                    }
                    else
                    {


                        Result.Text = "";
                        syuser = new SYUser();
                        syuser.UserName = UserNameTxt.Text;
                        string companyname = ddlcompany.SelectedItem.Text;
                        companyID = ddlcompany.SelectedItem.Value;
                        syuser.CompanyId = companyID;
                        syuser.StoreId = 0;
                        syuser.CreatedBy = Session["userLogon"].ToString();

                        syuser.ExpireDate = DateTime.Now;

                        userid = syuserconnector.SaveUser(syuser);

                        //UserIdtxt.Text = userid;

                        if (userid != null && userid != "")
                        {

                            //string userId = UserIdtxt.Text;
                            Collection<string> idsList = new Collection<string>();
                            foreach (GridViewRow row in GV.Rows)
                            {
                                CheckBox chk = (CheckBox)row.FindControl("CheckBox2");
                                if (chk != null && chk.Checked)
                                {
                                    string secId = GV.DataKeys[row.RowIndex].Value.ToString();

                                    idsList.Add(secId);

                                    //Response.Write("TaskId: " +secId + "<br/>");
                                    //Response.End();
                                }

                            }
                            syuserconnector.UpdateUserRoles(userid, idsList);
                            Result.Text = "User is Added and Roles are assigned to the User";

                        }


                    //}


                    //}
                }
            }
            //else
            //{
            //    Result.Text = "Username can only contain alpha-numeric characters. ";
            //}
        }


        protected void btnReset_Click(object sender, EventArgs e)
        {
            resetAllFields();
        }
        private void resetAllFields()
        {
            //UserIdtxt.Text = "";
            UserNameTxt.Text = "";
            Result.Text = "";
            ddlcompany.SelectedIndex = ddlcompany.Items.IndexOf(ddlcompany.Items.FindByValue("E-Payment"));

            foreach (GridViewRow row in GV.Rows)
            {
                CheckBox chk = (CheckBox)row.FindControl("CheckBox2");
                chk.Checked = false;
            }
        }
        protected void btngetuserobject_Click(object sender, EventArgs e)
        {

        }
        public void Getroles()
        {
            if (ValidatePage() == true)
            {
                Page.Validate();
                if (Page.IsValid)
                {
                    string companyID = ddlcompany.SelectedItem.Value;
                    //ArrayList companies = mConnector.GetGPCompanyIds();
                    //bool found = companies.Contains(companyID);
                    //if (found == true)
                    //{
                        Result.Text = "";
                        syuserconnector.UseLogFile = true;
                        syuserconnector.LogFilePath = Request.PhysicalApplicationPath + "logs\\azoxlog.txt";
                        Collection<string> idsList = new Collection<string>();

                        string companyname = ddlcompany.SelectedItem.Text;
                        companyID = ddlcompany.SelectedItem.Value;
                        // string ERPcompanyId;
                        //string companyID = "";
                        //if (companyname == "Fabrikam Inc")
                        //{
                        //    ERPcompanyId = "-1";
                        //    companyID = syutility.GetCompanyId(ERPcompanyId);
                        //}
                        //else
                        //{
                        // string companyID = syutility.GetCompanyId(companyname);
                        //}
                        //Response.Write(companyID);
                        Regex r = new Regex("[a-zA-Z]{1,40}");
                        string userid;
                        string username = UserNameTxt.Text;

                        if (username != null && r.IsMatch(UserNameTxt.Text.Trim()))
                        {
                            foreach (GridViewRow row in GV.Rows)
                            {
                                CheckBox chk = (CheckBox)row.FindControl("CheckBox2");
                                chk.Checked = false;
                            }
                            userid = syuserconnector.GetUserId(username, companyID);
                            //UserIdtxt.Text = userid;
                            // Response.Write("Test:" + userid);
                            if (userid != null && userid != "")
                            {

                                syuser = new SYUser();
                                syuser = syuserconnector.GetUserObject(userid);
                                idsList = syuser.RoleIds;
                                foreach (GridViewRow row in GV.Rows)
                                {
                                    string rolegv = GV.DataKeys[row.RowIndex].Value.ToString();
                                    // Response.Write(securitygv + "<br>");
                                    CheckBox chk = (CheckBox)row.FindControl("CheckBox2");
                                    if (syuser.RoleIds.Contains(rolegv))
                                    {
                                        chk.Checked = true;
                                    }
                                }
                            }
                            else
                            {
                                foreach (GridViewRow row in GV.Rows)
                                {
                                    CheckBox chk = (CheckBox)row.FindControl("CheckBox2");
                                    chk.Checked = false;
                                }
                                Result.Text = "User not in any roles for " + companyname;
                            }
                        }

                        //else
                        //   {
                        //       Result.Text = "Enter Username";
                        //   }

                    //}
                }
            }
        }




        protected void UserNameTxt_TextChanged(object sender, EventArgs e)
        {
            //string Username = UserNameTxt.Text;
            //resetAllFields();
            //UserNameTxt.Text = Username;

            //Page.Validate();
            //if (Page.IsValid)
            //{
            if (ValidatePage() == true)
            {
                //Regex r = new Regex("[a-zA-Z0-9]*$");
                //if (r.IsMatch(UserNameTxt.Text.Trim()))
                //{
                Getroles();
                //}
            }
        }

        protected bool ValidatePage()
        {
            Page.Validate();
            if (Page.IsValid)
            {
                Regex r = new Regex("[a-zA-Z0-9]");
                if (r.IsMatch(UserNameTxt.Text.Trim()))
                {
                    return true;
                }
                return false;
            }
            return false;

        }
    }
}

最佳答案

Initially I converted all of the queries to be parametrized queries. Since I have converted all of the parametrized queries to stored procedures.

很好。现在你的代码(已经)安全了 SQL Injection攻击。这 意味着SQL 命令是“安全的”,不会改变它们的结构。但是,它不能确保数据有效:数据有效性由 business rules 决定.

现在,客户端不应该被信任,因此,始终在后端执行数据验证。这可能在数据库(约束、触发器)或 DAL 或某些 ORM 或什至只是 ASP 代码隐藏(例如“验证器”)中。此外,可以在前端执行验证(例如 JavaScript);然而,这只是“第一道防线”,是为用户提供更多有用信息的一种方式。一些库/框架(例如 WCF RIA)允许以“统一”的方式描述这些业务规则

无论如何——它不再是“注入(inject)攻击”的问题,而是定义什么是有效数据并防止无效数据被接受。 (另请注意,稍后如何使用数据很重要。)

关于c# - 在 C# 中防止 SQL 注入(inject) asp.net,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9917601/

相关文章:

c# - CLR 如何在为结构分配空值时绕过抛出错误?

asp.net - 如何在 ASP.net 的 gridView 中设置每页的最大页面大小

asp.net - 如何使用Web API属性路由传递DateTime参数?

sql - SP :CacheHit Event in SQL Profiler 的说明

c# - 从任务中的异步 HttpWebRequest 调用捕获异常

c# - 使用 Caliburn.Micro 将 View 模型中的图像加载到 View 中

c# - 将 "Using"语句与类型化数据集表适配器一起使用

c# - 读取音频文件时出错?

sql - 在多个表中找到最常见的值

mysql - 使用 LEFT OUTER JOIN 检查相关行不存在的最佳方法是什么