我一直在努力治愈这个SQL注入的网站,我一直在努力的页面让我停了两天。
到目前为止,我正在验证来自客户端站点的用户输入。的RegularExpressionValidator。
在此页面上,这是用户唯一输入的输入。还有一个动态下拉列表正在使用服务器端验证进行验证。
用户名文本框中的数据也在使用Regex在客户端验证。
最初我将所有查询转换为参数化查询。因为我已将所有参数化查询转换为存储过程。
现在我不知道下一步该去哪儿了。从搜索论坛中,客户端验证和参数化查询的混合通常可以防止注入。
我觉得我在这里遗漏了一些东西。
附件是页面的代码以及c#中的usercontrol。任何方向都将非常感谢!
# <%@ 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;
}
}
}
答案 0 :(得分:3)
最初我将所有查询转换为参数化查询。因为我已将所有参数化查询转换为存储过程。
好。现在,您的代码(已经)可以免受SQL Injection攻击。此仅意味着SQL命令对于更改结构是“安全的”。但是,它无法确保数据有效:数据有效性由business rules确定。
现在,客户端不应该被信任所以,总是在后端执行数据验证。这可能在数据库(约束,触发器)或DAL或某些ORM中,或者甚至只是ASP代码隐藏(例如“验证器”)。另外,可以在前端执行验证(例如JavaScript);然而,这只是一个“第一道防线”,也是一种为用户提供更多有用信息的方法。一些库/框架(例如WCF RIA)允许以“统一”的方式描述这些业务规则。
在任何情况下 - 它不再是“注入攻击”的问题,而是定义有效数据并防止无效数据被接受。 (另请注意,以后如何消耗数据非常重要。)
答案 1 :(得分:0)
好的...当您的应用程序通过由连接文本形成的sql进行数据库调用时,可以执行Sql注入...而是需要使用参数化查询...
避免创建如下的SQL:
string sql = "Select * from Customer where Name = " + txtName.Text;
而是使用参数化查询...类似
"Select * from Customer where Name = @Name"
希望这会有所帮助......