How to prevent SQL Injection in a search form in asp - c#

I am working on a news based site. And the site has a search bar for the Newstitle and I don't want to let SQL injections happen on it.
What I am doing is to get the text from the textbox and then use a query to fetch the matching results. This is what happens when a user clicks the search button:
protected void button_Click(object sender, EventArgs e)
{
string connectionString = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
SqlConnection conn = new SqlConnection(connectionString);
try
{
SqlCommand comm = new SqlCommand("SELECT * FROM news
Where newstilte LIKE '%" + searchbox.text + "%'", conn);
conn.Open();
SqlDataReader reader = comm.ExecuteReader();
myRepeater.DataSource = reader;
myRepeater.DataBind();
reader.Close();
}
catch (Exception exception)
{
Response.Write(exception.ToString());
}
finally
{
conn.Close();
}
}
As you can see I then use a repeater to show the results. I am wondering how can I prevent SQL injection in the part where people write in the textbox.

USE PARAMETRIZED QUERIES AS BELOW:
protected void button_Click(object sender, EventArgs e)
{
string connectionString = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
SqlConnection conn = new SqlConnection(connectionString);
try
{
SqlCommand comm = new SqlCommand("SELECT * FROM news
Where newstilte LIKE '%' + #newstilte + '%'", conn);
cmm.Parameters.AddWithValue("#search",searchbox.text) ;
conn.Open();
SqlDataAdapter reader = comm.ExecuteReader();
myRepeater.DataSource = reader;
myRepeater.DataBind();
reader.Close();
}
catch (Exception exception)
{
Response.Write(exception.ToString());
}
finally
{
conn.Close();
}
}
EDIT:
You can also use following if you have datatype kind of restriction for search.
cmm.Parameters.Add(new SqlParameter("#search", SqlDbType.VarChar));
cmm.Parameters["#search"].Value = searchbox.text;
Have a look at THIS doccument.

Try
SqlCommand comm = new SqlCommand("SELECT * FROM news
Where newstilte LIKE '%' + #newstilte + '%'", conn);
comm.Parameters.AddWithValue("#newstilte",searchbox.text)

Use stored procedures with parameters.
.net SQL library properly
SqlCommand comm = new SqlCommand("StoredProcedureName")
comm.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#Parameter", Value)
The .net library should handle most injections.

Related

Query Runs in Ms Access Database But Not When Executed From Application

Query with parameters works perfectly in ms access database. But when I supply the same parameters from C# winforms application it returns no records.
If the parameter is passed to the query then it will use that parameter in where clause, otherwise it will retrieve all records.
bus table sample data:
Ms-Access Query:
PARAMETERS parPlateNo Text ( 255 );
SELECT bus.*
FROM bus
WHERE (((bus.plateNo) Like IIf(IsNull([parPlateNo]), True ,"%" & [parPlateNo] & "%")));
C# Code:
using (OleDbConnection conn = new OleDbConnection(myGlobals.connString))
{
using (OleDbDataAdapter adapter = new OleDbDataAdapter())
{
using (OleDbCommand cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "qryBus";
if(plateNo == "")
cmd.Parameters.AddWithValue("?", DBNull.Value);
else
cmd.Parameters.AddWithValue("?", plateNo);
adapter.SelectCommand = cmd;
dsDetails = new DataSet();
adapter.Fill(dsDetails, "details");
}
}
}
PlateNo is a text column.
Remarks: If I remove the like statement in ms access query and run the same code in C#, it will run perfectly and retrieve all the records in table.
After that, I display the data in datagridview using bindingsource.
Why this is happening?
You using oleDB. You have to change that query and use % as wild cards. DAO, and native Access you use *, but for ADO, or oleDB, you have to use % as the wild cards.
Here are a couple of examples that should help you get this up and running.
private void button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Server=Your_Server_Name;Database=AdventureWorksLT2012;Trusted_Connection=True");
try
{
cmd = new SqlCommand("insert into [dbo].[Student] values(#a,#b,#c)", con);
cmd.Parameters.AddWithValue("#a", int.Parse(textBox1.Text));
cmd.Parameters.AddWithValue("#b", textBox2.Text);
cmd.Parameters.AddWithValue("#c", textBox3.Text);
con.Open();
a = cmd.ExecuteNonQuery();
if (a > 0)
{
MessageBox.Show("Data Submited");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
con.Close();
}
}
AND
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Server=Your_Server_Name;Database=AdventureWorksLT2012;Trusted_Connection=True");
try
{
cmd = new SqlCommand("select * from student where sid=#a", con);
cmd.Parameters.AddWithValue("#a",int.Parse(comboBox1.SelectedItem.ToString()));
con.Open();
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
if (dr.Read())
{
textBox1.Text = dr["sid"].ToString();
textBox2.Text = dr["fname"].ToString();
textBox3.Text = dr["lname"].ToString();
//label1.Text = dr["cdate"].ToString();
}
}
dr.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
con.Close();
}
}

The error says "The ConnectionString property has not been initialized" in c#

this code is for the combo box where i want to select some index to show it to my textboxes.
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
conn.Open();
cmd.Connection = conn;
string query = "SELECT * FROM GuestInfo WHERE Groomno= '" + comboBox2.Text + "'";
db.connectDB();
db.da.SelectCommand = new OleDbCommand(query, db.conn);
db.executeQryCommand(query, false);
maxRecord = db.ds.Tables[0].Rows.Count;
loadRecords(recordCounter);
cmd.CommandText = query;
dr = cmd.ExecuteReader();
while (dr.Read())
{
textBox1.Text = dr["Gname"].ToString();
textBox2.Text = dr["Gcontactno"].ToString();
}
conn.Close();
}
catch (Exception er)
{
MessageBox.Show("Error! " + er.Message);
}
}
//My program is completely running but not in this section. :(
Is you made an connection between your application and database source using conn object ? You might be used conn object as a connection object but before this was you initialized you Connection ?
Simpy use like
"SqlConnection conn=new SqlConnection("Connection_Source");"
here is your error.
You have to define the connection string for the connection, here i suggest you one best method for executing command.
using (OleDbConnection conn = new OleDbConnection("yourconnectionString"))
{
conn.Open();
using (OleDbCommand cmd =new OleDbCommand("your query text", conn))
{
// execute your command
}
}
If its just to select value from comboBox and display in textBox , then below code will help you...
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
conn.Open();
OleDbCommand cmd = new OleDbCommand("SELECT Gname,Gcontactno FROM GuestInfo WHERE Groomno= '" + comboBox2.Text + "'", conn);
OleDbDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
textBox1.Text = dr[0].ToString();
textBox2.Text = dr[1].ToString();
}
conn.Close();
}
catch (Exception er)
{
MessageBox.Show("Error! " + er.Message);
}
}

How to add data into Specified columns in mysql using c#

How to add data into Specified columns in mysql database table using c# button click, once i clicked the button it will be passing to the catch
here is my add button code
private void Button_add_Click(object sender, RoutedEventArgs e)
{
try
{
string Query = #"INSERT INTO `bcasdb`.`tbl_department`(
`dep_id`,
`dep_name`,
`tbl_branch_branch_id`)
VALUES ("
+ this.depIDInput.Text + ",'"
+ this.depnameInput.Text + "','"
+ this.dep_branchIDInput.Text + "')";
//This is command class which will handle the query and connection object.
MySqlConnection conn = new MySqlConnection(BCASApp.DataModel.DB_CON.connection);
MySqlCommand cmd = new MySqlCommand(Query, conn);
MySqlDataReader MyReader;
conn.Open();
MyReader = cmd.ExecuteReader();// Here our query will be executed and data saved into the database.
conn.Close();
successmsgBox();
}
catch (Exception)
{
errormsgBox();
}
}
here is all the columns of the table,
INSERT INTO `bcasdb`.`tbl_student`
(`reg_id`,
`std_fname`,
`std_lname`,
`tbl_batch_batch_id`,
`gender`,
`dob`,
`email`,
`mobile`,
`contact_address`,
`home_address`,
`status`,
`course_id`,
`depart_id`,
`parent_name`,
`telephone`,
`nationality`,
`nic`,
`passport_no`,
`acadamic_qulification`,
`current_employement`,
`gce_ol`,
`gce_al`,
`birth_certifiacte`,
`copy_of_nic`,
`police_clerence`,
`tbl_studentcol`)
VALUES
I believe your code should be rewritten as following:
private void Button_add_Click(object sender, RoutedEventArgs e)
{
try
{
string Query = #"INSERT INTO `bcasdb`.`tbl_department`(
`dep_id`,
`dep_name`,
`tbl_branch_branch_id`)
VALUES (#depId, #depName, #branchId)";
//This is command class which will handle the query and connection object.
using (MySqlConnection conn = new MySqlConnection(BCASApp.DataModel.DB_CON.connection))
{
conn.Open();
using (MySqlCommand cmd = new MySqlCommand(Query, conn))
{
cmd.Parameters.Add("#depId", this.depIDInput.Text);
cmd.Parameters.Add("#dep_name", this.depnameInput.Text);
cmd.Parameters.Add("#branchId", this.dep_branchIDInput.Text);
cmd.ExecuteNonQuery();
}
}
successmsgBox();
}
catch (Exception)
{
errormsgBox();
}
}

How Do I Populate Text Boxes With Sql Database Data Using One Combo Box

Hey everyone pretty new to SQL Database functions but have been coding in c# for about a year now still not that great at it but I'm getting there!
I'm currently creating a football application and to Edit players and Matches i was wanting to use one drop down combo box to retrieve data from an SQL database which then would populate other text boxes and combo boxes. I've had a go at it myself but don't know where i'm going wrong.
On form load my connection opens i populate my datasets and i execute this method to populate my combobox
private void Navigate()
{
string showPlayers = "SELECT * From Add_Players";
SqlCommand cmdData = new SqlCommand(showPlayers, conn);
SqlDataReader myReader = cmdData.ExecuteReader();
while (myReader.Read())
{
comboEditPlayer.Items.Add(myReader[0]);
}
conn.Close();
}
After which in the combo box selected index changed method i have this code
private void comboEditPlayer_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
conn.Open();
string showPlayers = "SELECT * From Add_Players WHERE Player_ID ='"
+ comboEditPlayer + "' ;";
SqlCommand cmdData = new SqlCommand(showPlayers, conn);
SqlDataReader myReader = cmdData.ExecuteReader();
while (myReader.Read())
{
comboEditPlayerPos.Items.Add(myReader[1]);
txtEditPlayerName.Text = myReader[2].ToString();
txtEditPlayerSecond.Text = myReader[3].ToString();
comboEditPlayerStatus.Items.Add(myReader[4]);
}
conn.Close();
conn.Dispose();
}
catch (Exception comboFail)
{
MessageBox.Show(comboFail.ToString());
}
}
I've been told this code is open and i need to use parameterized queries for preventing hacker attempts which i have started but do not know what Parameter i should be adding to the code i have for this is below
private void comboEditPlayer_SelectedIndexChanged(object sender, EventArgs e)
{
string connectionString =
ZimbFootball.Properties.Settings.Default.Football2ConnectionString;
using (SqlConnection connection = new SqlConnection (connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(
"SELECT * From Add_Players WHERE Player_ID ="
+ comboEditPlayer.SelectedValue + "", connection))
{
command.Parameters.Add(new SqlParameter ("",));
}
}
}
All help is appreciated and please go easy on me :P
You could add a parameter to the collection with the value of your ComboBox, then execute the query and read back the values from the reader
private void comboEditPlayer_SelectedIndexChanged(object sender, EventArgs e)
{
string connectionString =
ZimbFootball.Properties.Settings.Default.Football2ConnectionString;
using (SqlConnection connection = new SqlConnection (connectionString))
using (SqlCommand command = new SqlCommand(
"SELECT * From Add_Players WHERE Player_ID =#id", connection))
{
connection.Open();
command.Parameters.AddWithValue("#id", comboEditPlayer.Text);
using(SqlDataReader myReader = command.ExecuteReader())
{
while (myReader.Read())
{
comboEditPlayerPos.Items.Add(myReader[1]);
txtEditPlayerName.Text = myReader[2].ToString();
txtEditPlayerSecond.Text = myReader[3].ToString();
comboEditPlayerStatus.Items.Add(myReader[4]);
}
}
}
}

What is the optimal / standard method of using a sql connection?

protected void populateDataGrid()
{
string connectionString = configurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
string command = "select * from student";
SqlDataAdapter dataAdapter = new SqlDataAdapter(command, connectionString);
DataSet data = new DataSet();
dataAdapter.Fill(data);
GridView1.DataSource = data;
GridView1.DataBind();
}
protected void Button2_Click(object sender, EventArgs e)
{
string connectionString = ConfigurationManager.ConnectionStrings["sqlstudentConnectionString"].ConnectionString;
string command = #"INSERT INTO [student] (studentID, studentFirstName, studentLastName)
VALUES (" + TextID.Text + ", '" + TextFirstName.Text + "', '" + TextLastName.Text + "')";
SqlConnection sqlConnection = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = command;
cmd.Connection = sqlConnection;
sqlConnection.Open();
cmd.ExecuteNonQuery();
sqlConnection.Close();
TextID.Text = "";
TextFirstName.Text = "";
TextLastName.Text = "";
populateDataGrid();
}
The first function gets all the table data and dumps it to a gridview.
The second function takes input and inserts it into the database.
How can these functions be condensed or simplified?
How can these functions be condensed or simplified?
I would focus on correctness before simplification. Currently I can see at least two problems with the code:
You should absolutely use parameterized SQL instead of putting the values into the SQL itself. Your current code is prone to SQL injection attacks.
You should use using statements so that connection and command are both closed automatically even if exceptions are thrown.
Then in terms of simplification:
You can use the SqlCommand constructor which takes the text and connection - the type defaults to Text anyway.
I would personally try to separate the UI code from the storage code, at least for a non-trivial project. You should look at ASP.NET MVC, at least to get some idea of separation, even if you don't change to start using it.
In Button2_Click(object sender, EventArgs e) method , you need to use parametrized query to avoid SQL Injection.
That is the standard way.
protected void Button2_Click(object sender, EventArgs e)
{
string connectionString = ConfigurationManager.ConnectionStrings["sqlstudentConnectionString"].ConnectionString;
string command = #"INSERT INTO [student] (
studentID, studentFirstName, studentLastName
) VALUES (
#studID, #FName, #LName
)";
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = command;
cmd.Parameters.AddWithValue("#studID", TextID.Text);
cmd.Parameters.AddWithValue("#FName", TextFirstName.Text);
cmd.Parameters.AddWithValue("#LName", TextLastName.Text);
cmd.Connection = sqlConnection;
sqlConnection.Open();
cmd.ExecuteNonQuery();
sqlConnection.Close();
}
TextID.Text = "";
TextFirstName.Text = "";
TextLastName.Text = "";
populateDataGrid();
}
Hope Its Helpful.

Categories

Resources