Please help me to prevent my data from SQL injection.
I have replaced ' with '' (single quote with 2 quote) while doing any operation on sql server.
Please tell me what all i need to do , to prevent my application from SQL injection. my application is in asp.net 2.0
i will use parameterized queries but what about my old projects.. i mean what about where i have written a string query and sending it to sql server as a commandtext.
Please tell me can any one insert sql injection even i have replaced ' with ''?
The best you can do is to use parameterized queries, if the language/framework supports it.
EDIT: asp.net can handle it. Use SqlCommand
An example from here -
private static void UpdateDemographics(Int32 customerID,
string demoXml, string connectionString)
{
// Update the demographics for a store, which is stored
// in an xml column.
string commandText = "UPDATE Sales.Store SET Demographics = #demographics "
+ "WHERE CustomerID = #ID;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
command.Parameters.Add("#ID", SqlDbType.Int);
command.Parameters["#ID"].Value = customerID;
// Use AddWithValue to assign Demographics.
// SQL Server will implicitly convert strings into XML.
command.Parameters.AddWithValue("#demographics", demoXml);
try
{
connection.Open();
Int32 rowsAffected = command.ExecuteNonQuery();
Console.WriteLine("RowsAffected: {0}", rowsAffected);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Instead of cleaning up the SQL manually, you should be using a library to access SQL.
Do not build up query string manually and if you need to pass parameters through, use parameterized queries and stored procedures.
See this example in VB.NET.
I'm not certain, but I don't think there's any quick easy way to protect your old projects from SQL injection attacks.
I think your best bet would probably be to actually modify the data access code in your old projects to use parameterised queries.
Or, you could do as Oded suggests and re-write your old projects using a library.
Related
I have trouble converting this to stored procedure
//The string included in the sql statement:
string employer = Session["Employer"].ToString();
then the sql statement
update tblWorkData set EmployerName='"+txtemployername.text+"' where EmployerName='"+Employer+"' //the string above
This works fine in asp.net
But when I turn it into stored procedure,
create proc updateWork
#EmployerName nvarchar(max)
as
begin
update tblWorkData set EmployerName=#EmployerName where EmployerName=#EmployerName
end
Now when I execute the sp on asp.net,
string update = "updateWork '"+employer+"','"+txtemployername.text+"'";
I got an error saying "too many arguements". What should I do?
Your stored procedure only takes one argument and you're calling it with two. To fix this you need to alter the procedure to take two arguments like this:
create proc updateWork
#EmployerName nvarchar(max),
#Employer nvarchar(max)
as
begin
update tblWorkData set EmployerName=#EmployerName where EmployerName=#Employer
end
I changed the whereclause as I guess you meant it to be. As it was before it didn't actually do anything at all.
On a side note you might want to look into how to properly call procedures and how to add parameters in a way that isn't vulnerable to SQL injection.
You have to connect to the database in order to execute sql statements:
string employer = Session["Employer"].ToString();
// assume connectionString is a valid connection string
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
command.CommandText = "updatework";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#EmployerName", employer);
command.ExecuteNonQuery();
}
over the past week or so I've been building an ASP site that connects to a Sql-Server 2008 database. I've never used Stored procedures and I was wondering if anyone could give me some guidance on how to create and how to use them within an ASP method. I'm trying to make the code of the website as simple and elegant as possible. Here's the code I'm trying to change into a stored procedure:
private void ExecuteInsert(string name, string type)
{
SqlConnection conn = new SqlConnection(GetConnectionStringHM());
string sql = "INSERT INTO tblSoftwareTitles (SoftwareName, SoftwareType) VALUES "
+"(#SoftwareName,#SoftwareSystemType)";
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
SqlParameter[] param = new SqlParameter[2];
//param[0] = new SqlParameter("#SoftwareID);
param[0] = new SqlParameter("#SoftwareName", SqlDbType.NVarChar, 200);
param[1] = new SqlParameter("#SoftwareType", SqlDbType.Int);
param[0].Value = name;
param[1].Value = type;
for (int i= 0; i < param.Length; i++)
{
cmd.Parameters.Add(param[i]);
}
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
catch (System.Data.SqlClient.SqlException ex)
{
string msg ="Insert Error:";
msg += ex.Message;
throw new Exception(msg);
}
finally
{
conn.Close();
}
}
This is just a Simple insert that takes two parameters from an entry form and inserts them into the database. Any Help with this would be much appreciated as I feel it would be a useful thing to know later on down the line. Thanks in advance!
You should look in to MSDN basics: http://msdn.microsoft.com/en-us/library/bb896274.aspx
You don't need to complicate things using for loop.
try
{
sqlConnection = new SqlConnection(dbConnectionString);
SqlCommand command = new SqlCommand(sql, sqlConnection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#SoftwareName", SqlDbType.NVarChar, 200).Value = SoftwareNameHere;
command.Parameters.Add("#SoftwareType", SqlDbType.Int).Value = SoftwareTypeHere;
sqlConnection.Open();
return command.ExecuteNonQuery();
}
catch (SqlException ex)
{
Console.WriteLine("SQL Error" + ex.Message.ToString());
return 0;
}
finally
{
conn.Close();
}
If you are using .NET 3.5 or above, you can use the USING code block which takes care of the disposal of your resources. I am not entirely sure, but from what I remember this was introduced with .NET 3.5 to replace Try/Finally code block (which required developers to dispose the resources like connection object manually through code).
using (SqlConnection con = new SqlConnection { dbConnectionString })
{
con.Open();
try
{
using (SqlCommand command = new SqlCommand { CommandType = CommandType.StoredProcedure, Connection = con, CommandTimeout = 300, CommandText = "sp_Test" })
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#SoftwareName", SqlDbType.NVarChar, 200).Value = SoftwareNameHere;
command.Parameters.Add("#SoftwareType", SqlDbType.Int).Value = SoftwareTypeHere;
command.ExecuteNonQuery();
}
}
catch(SqlException ex)
{
//ex.ToString message here;
}
}
The answer you're looking for is at this SO post...
https://stackoverflow.com/a/4561443/1246574
The one thing I would improve upon for the accepted answer in that post, is the example in that answer doesn't use any USING statements. It would be better to have the connection and command within USING statements so they are automatically disposed.
Another approach would be to use the Microsoft Enterprise Library for interacting with your SQL Server DB. I think it's easier than using plain old SqlConnection and SqlCommand.
Since your code already uses parameters, you are 90% of the way there. All you have to do is:
Put the insert statement into a stored procedure, keeping the same parameter definitions as the dynamic statement.
Change CommandType.Text to CommandType.StoredProcedure
Change the command text to be just the name of the stored procedure.
Having done some reading on the subject I've come across some useful articles that really do question my need for stored procedures.
This article gives a good Viewpoint on how stored procedures can be more of a hassle than a help and are quite clunky and tedious in terms of coding, debugging ad error reporting.
http://www.codinghorror.com/blog/2004/10/who-needs-stored-procedures-anyways.html
And this article (linked in the one above) gives a good explanation on parametrized, explaining why they are necessary to reduce the risk of sql injections and also raises the point that these parametrized queries are cached in a similar way to procedures, giving them comparable performance gains
http://www.uberasp.net/getarticle.aspx?id=46
I feel that In my situation keeping parametrized sql Queries coded into my ASP pages will be the smartest move as these pages will be stored on a server and accessed by clients. I imagine if this were an application installed on several client machines hard coding the SQL wouldn't be a desirable option and so Stored procedures would be the best way to go (to my knowledge)
A follow Up to Stored procedures verses Parametrized sql can be found here with different links to each side of the argument if those are interested.
http://www.codinghorror.com/blog/2005/05/stored-procedures-vs-ad-hoc-sql.html
Hope this little answer helps out anyone else considering using stored procedures over parametrized SQL and vice-versa
I'm a new in the world of coding,
I built a large web site with several textboxes, so now i figure out that I've been using a dangerous method of inserting data in the SQL server by some thing like this:
execSQL("insert into Dossier(ID_Dossier,Nom_Giac) values(" & id_dossier.text & "," Nom_gaic.text & "')")
Public Function execSQL(ByVal req As String, Optional ByVal type As String = "r")
cmd = New SqlCommand
cmd.CommandText = req
cmd.Connection = con
openCon()
If type = "r" Then
Return cmd.ExecuteReader(CommandBehavior.CloseConnection)
Else
Return cmd.ExecuteNonQuery
End If
closeCon()
End Function
I just want to know if there is any quick way to solve this problem in my entire web site.
I applaud the fact that you want to remove any possibilities of SQL injection from your site.
That said, there's no quick, magical "find-and-replace-my-vulnerable-code" function; you need to go into your system and update any calls like that with parameterized queries.
Parameterized queries are required to prevent SQL injection. Here's an example, taken from this question: How do I create a parameterized SQL query? Why Should I?
Public Function GetBarFooByBaz(ByVal Baz As String) As String
Dim sql As String = "SELECT foo FROM bar WHERE baz= #Baz"
Using cn As New SqlConnection("Your connection string here"), _
cmd As New SqlCommand(sql, cn)
cmd.Parameters.Add("#Baz", SqlDbTypes.VarChar, 50).Value = Baz
Return cmd.ExecuteScalar().ToString()
End Using
End Function
Using LINQ to SQL can help prevent SQL Injection attacks by parameterizing for you:
LINQ to SQL passes all data to the database via SQL parameters. So, although the SQL query is composed dynamically, the values are substitued server side through parameters safeguarding against the most common cause of SQL injection attacks.
Read more about it here.
I have the following code snippet.
SqlCommand cmd = new SqlCommand("SELECT FName,LName FROM EMPLOYEE_TABLE WHERE EmployeeID = '" +TextBox1.Text + "' AND Password = '"+ TextBox2.Text +"'", con);
SqlDataReader x = cmd.ExecuteReader();
try
{
if (x.Read())
{
name = (string)x["FName"] +' '+ (string)x["LName"];
Session["NAME"] = name;
Session["ID"] = TextBox1.Text;
Response.Redirect("sample.aspx?action=On_Click");
}
else
{
errormsg.Text = "login failed.Please enter Valid UserID and Password";
errormsg.ForeColor = System.Drawing.Color.Red;
}
}
catch (Exception exp)
{
errormsg.Text = "Sorry,You dont have access to this portal.";
}
finally
{
x.Close();
con.Close();
}
Now, when i use a valid id (that exists) and password as abc' or 'x'='x then it logs in into the first account of the table in the database. Till this it's fine.
However when I try to debug the code, it throws an error Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack..
Also if it is throwing an error then why is it logging into this 1st account of the database. Note: the first account of the database has a different userid than that which i m providing.
Note: I am the developed of this application. So I'm not doing anything illegal. :)
Look at this part of your SQL:
"' AND Password = '"+ TextBox2.Text +"'"
With your password, it's
"' AND Password = ''x'='x'"
which is not the SQL you want.
Even if you are trying to do SQL injection, you have to result in valid SQL. Usually, it's by ending the statement with a semi-colon after closing the quote. See this:
http://xkcd.com/327/
OK, to provide an answer based on the primary issue you've got (as you've stated, you're new to the SQL Injection issue).
SQL Injection is caused by dynamically building a SQL query using user input as part of the construction. The simplest solution to this in .Net is to create a parameterized query.
I think Jeff Atwood has the most complete yet concise article providing an explanation and complete example here
Quoted from above link:
SqlConnection conn = new SqlConnection(_connectionString);
conn.Open();
string s = "SELECT email, passwd, login_id, full_name " +
"FROM members WHERE email = #email";
SqlCommand cmd = new SqlCommand(s);
cmd.Parameters.Add("#email", email);
SqlDataReader reader = cmd.ExecuteReader();
The issue at hand:
The reason it's still logging into the account is because the query is still "valid".
The statement will still be executed, and the relevant record will still be returned from the database, no exception will be thrown.
The only way you will stop the login process when invalid data is provided is to validate the input before executing the query. You should always validate user input before sending it off to the database. If the user were to provide:
username'; drop table users;--
as the username, you would be in a LOT of trouble.
The error you're encountering is a debugging error, not an actual program exception. That's why it works when you run it normally.
To remedy the error, I'd first make sure that everything is running with a Debug build. Also, make sure you're currently debugging in the function of the variable you want to inspect. Try stepping (F10) a few times past your breakpoint to refresh the context. There are a slew of other suggestions on the internet for that particular error, so if you're still having problems you might have to do some googling.
Okay this question could either be very broad or very specific because I am not sure if I am going about this in a fundamentally wrong way or if I am close to correct.
First an overview: What I am trying to do it create a server application for all of the clients in my organization to connect to. I think the best way to do this is to use a web service. Please correct me if I am wrong!
Anyway, if I use a web service I need the web service(server) to connect to the database. In MS Visual studio when you add a web service project the data menu disappears and you can't add a data source to the project. There may be a workaround for this by hand coding this, but I am not sure how to do it. This is my first time working with a web service and ASP.NET so I am a real noob in this area.
Any help would be greatly appreciated!!!
Add your database connection string to the <connectionStrings/> section of the web service web.config file. Check this web site for a list of the most common database connection strings: Connectionstrings.com
You would use standard ADO.Net commands and SQL statements, rather than using the dataset designer. Example (IN VB)
<WebMethod()> _
Public Function DoesOpenCallExist(ByVal CustID As String, ByVal CallType As String, ByVal SubCallType As String) As Boolean
Dim returnvalue As Boolean = False
' first, entry validation
' snip - code deleted
Dim conn As New System.Data.SqlClient.SqlConnection
conn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings("HEATConnectionString").ConnectionString
Dim cmd As New SqlClient.SqlCommand
cmd.Connection = conn
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "sp_GetCallCount"
cmd.Parameters.AddWithValue("#CustID", CustID)
' Etc...
Try
conn.Open()
returnvalue = cmd.ExecuteScalar() > 0
Catch ex As Exception
Throw New Exception(ex.ToString())
Finally
conn.Close()
End Try
Return returnvalue
End Function
*This should be done
web.config file*
here the datsource is the servername,initial catlog is the databasename and the userid ur sql userid and the password is as same.
And then in the class we want to get connect with the database......
****class.cs****
public class connect
{
public static SqlConnection con()
{
String con= ConfigurationManager.AppSettings["connections"].ToString();
SqlConnection cn = new SqlConnection(con);
cn.Open();
return cn;
}
}
here the connection is the keyname......
ok i think its sufficient............