I have some questions about how to prevent sql injectiion with the help of parameterised queries
sqlQuery="SELECT * FROM usersTbl WHERE username=#uname AND password=#passwd";
SqlCommand cmd = new SqlCommand(sqlQuery, conn);
SqlParameter[] par = new MySqlParameter[2];
par[0] = new SqlParameter("#uname ", SqlDbType.VarChar,25);
par[1] = new SqlParameter("#passwd", SqlDbType.VarChar, 45);
And then I attach them to the SqlCommand and ExecuteScalar it.
For example the client insert the string ;DROP -- in the password variable, will the parameterised query prevent the DROP query to be executed ?
Thank you
Of course, when the client pass ';DROP -- value in the password field, this will be parsed into
SELECT *
FROM usersTbl
WHERE username=#uname AND password=''';DROP --'
The command object will automatically escapes any single quotes found on the value.
UPDATE 1
As, I already told you, it won't. Because the quotes will be escaped by doubling the quotes. Example,
string pass_val = "'; DROP usersTbl;--";
when you passed that into command and its value is parameterized, this will become
SELECT * FROM usersTbl WHERE ... AND password='''; DROP usersTbl;--'
and NOT
SELECT * FROM usersTbl WHERE ... AND password=''; DROP usersTbl;--
Yes, the parameterized query will correctly escape any characters that would allow this to happen.
Related
FbCommand fbCmm =
new FbCommand("INSERT INTO PRODUTO
(CODIGO,EAN,DESCRICAO,VAL_PRODUTO,VAL_CUSTO,CAT_PRECO)"
+ "Values (#txt_codigo.Text, #txt_ean, #txt_descricao,
#txt_valPro, #txt_valCus, #txt_catPre)", ConexaoFirebird.Conexao);
What's wrong with that sentence?
I did a open connection in other class - ConexaoFirebird.Conexao();
You're executing a parameterized query without providing values for those parameters. See the documentation:
FbCommand cmd = new FbCommand("insert into t1(id, text) values (#id, #text);");
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#id", 123);
cmd.Parameters.Add("#text", "my string");
cmd.ExecuteNonQuery();
Here they bind the values 123 and "my string" to the parameters named id and text respectively.
Also note that parameter names are generally rescticted to alphanumeric, so txt_codigo.Text isn't likely going to work.
You should use quote for decimal, string field types, your statement is correct but not clear, you can create clear sql text with sql command builder or you can use Command object of your connection.
This question already has answers here:
SqlCommand with Parameters
(3 answers)
Closed 8 years ago.
Hi this is my query
SELECT StraightDist FROM StraightLineDistances
WHERE (FirstCity='007' AND SecondCity='017');
How can I pass this in to sql statement?
I want to replace the city numbers '007' and '017' with variables
string destcity;
string tempcityholder1;
What I tried is this
SqlCommand mybtncmd2 = new SqlCommand("SELECT StraightDist FROM StraightLineDistances WHERE (FirstCity='" + tempcityholder1 + "' AND SecondCity='" + destcity + "');", mybtnconn2);
it didn't give me the expected output.
But when i tried with the original sql as given below it worked.
SqlCommand mybtncmd2 = new SqlCommand("SELECT StraightDist FROM StraightLineDistances WHERE (FirstCity='007' AND SecondCity='017');", mybtnconn2);
Can anyone point me the error here?
or a better solution.
This is for a personal application, security is not a must, so no need of parametrized queries. And I don't know how to implement parametrized queries with multiple parameters. If anyone can explain how to use a parametrized query it's great and I would really appreciate that. But just for the time being I need to correct this.
Any help would be great..
OK if with parametrized query
MY Work looks like this
SqlConnection mybtnconn2 = null;
SqlDataReader mybtnreader2 = null;
mybtnconn2 = new SqlConnection("");
mybtnconn2.Open();
SqlCommand mybtncmd2 = new SqlCommand("SELECT StraightDist FROM StraightLineDistances WHERE (FirstCity='007' AND SecondCity='017');", mybtnconn2);
mybtnreader2 = mybtncmd2.ExecuteReader();
while (mybtnreader2.Read())
{
MessageBox.Show(mybtnreader2.GetValue(0) + "My btn readre 2 value");
}
Can anyone give me a solution which doesn't complicate this structure.
If I use a parametrized query how can I edit
mybtnreader2 = mybtncmd2.ExecuteReader();
This statement?
This is the way to use parametrized queries:
string sqlQuery="SELECT StraightDist FROM StraightLineDistances WHERE (FirstCity= #tempcityholder1 AND SecondCity=#destcity);"
SqlCommand mybtncmd2 = new SqlCommand(sqlQuery, mybtnconn2);
mybtncmd2.Parameters.AddWithValue("tempcityholder1", tempcityholder1 );
mybtncmd2.Parameters.AddWithValue("destcity", destcity);
It's always good practice to use parameters, for both speed and security. A slight change to the code is all you need:
var mybtncmd2 = new SqlCommand("SELECT StraightDist FROM StraightLineDistances WHERE FirstCity=#City1 AND SecondCity=#City2;", mybtnconn2);
mybtncmd2.Parameters.AddWithValue("#City1", "007");
mybtncmd2.Parameters.AddWithValue("#City2", "017");
Use prepared statements: it's both easy and secure.
command.CommandText =
"INSERT INTO Region (RegionID, RegionDescription) " +
"VALUES (#id, #desc)";
SqlParameter idParam = new SqlParameter("#id", SqlDbType.Int, 0);
SqlParameter descParam =
new SqlParameter("#desc", SqlDbType.Text, 100);
You really won't do this, because this is an open door to SQL injection.
Instead you should use Stored Procedures for that approach.
In case your not familiar with SQL injection, let's make it clear:
Assume that you have a database with a table called 'T_USER' with 10 records in it.
A user object has an Id, a Name and a Firstname.
Now, let's write a query that select a user based on it's name.
SELECT * FROM T_USER WHERE Name= 'Name 1'
If we take that value from C#, this can really take unexpected behaviour.
So, in C# code we will have a query:
string queryVal;
var command = "SELECT * FROM T_USER WHERE Name = '" + queryVal + "'";
As long as the user is nice to your application, there's not a problem.
But there's an easy way to retrieve all records in this table.
If our user passes the following string in QueryVal:
demo' OR 'a' = 'a
Then our query would become:
SELECT * FROM T_USER WHERE Name = 'demo' OR 'a' = 'a'
Since the second condition is always true, all the records are retrieved from this table.
But we can even go further:
If the same user uses the following value in queryVal:
demo'; DELETE FROM T_USER--
The full query becomes:
SELECT * FROM T_USER WHERE Name = 'demo'; DELETE FROM T_USER--'
And all our records our gone.
And we can even go further by dropping the table:
queryVal needs to be:
demo'; DROP TABLE T_USER--
I think you get it. For more information google on Sql Injection:
I have the statement in c# :
String sql = String.Format("UPDATE Table SET FIRST_NAME='{0}',LAST_NAME='{1}',BIRTH_DATE='{2}' where CUSTOMER_NUMBER ='{3}'",FirstName, LastName,DateOfBirth,Number);
The above statement doesn't execute if the first name,last name etc have apostrophe like O'Hare,O'Callahagan because of this the update statement gets the wrong syntax.
How to escape the apostrophe in string.format?
How to escape the apostrophe in string.format?
Don't escape it, use parameterized query instead.
Imagine a user with a really unconventional name strongly resembling SQL statements for dropping a table or doing something equally malicious. Escaping quotes is not going to be of much help.
Use this query instead:
String sql = #"UPDATE Table
SET FIRST_NAME=#FirstName
, LAST_NAME=#LastName
, BIRTH_DATE=#BirthDate
WHERE CUSTOMER_NUMBER =#CustomerNumber";
After that, set values of FirstName, LastName, DateOfBirth, and Number on the corresponding parameters:
SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.AddWithValue("#FirstName", FirstName);
command.Parameters.AddWithValue("#LastName", LastName);
command.Parameters.AddWithValue("#BirthDate", BirthDate);
command.Parameters.AddWithValue("#CustomerNumber", CustomerNumber);
Your RDMBS driver will do everything else for you, protecting you from malicious exploits. As an added benefit, it would let you avoid issues when the date format of your RDBMS is different from your computer: since your date would no longer be passed as a string representation, there would be no issues understanding which part of the formatted date represents a day, and which one represents a month.
You should use parameterized queries:
using (SqlCommand cmd = new SqlCommand("UPDATE Table SET FIRST_NAME= #FirstName, LAST_NAME= #LastName, BIRTH_DATE=#BirthDate where CUSTOMER_NUMBER = #CustomerNumber"))
{
cmd.Parameters.Add(new SqlParameter("FirstName", FirstName));
cmd.Parameters.Add(new SqlParameter("LastName", LastName));
cmd.Parameters.Add(new SqlParameter("BirthDate", DateOfBirth));
cmd.Parameters.Add(new SqlParameter("CustomerNumber", Number));
// Now, update your database
} // the SqlCommand gets disposed, because you use the 'using' statement
By using parameterized queries, you solve your problem. Using parameterized queries has two other advantages:
Protection against SQL Injection
Readability
Use parameterized query.
string commandString = "insert into MyTable values (#val1, #val2)";
SqlCommand command = new SqlCommand(commandString, connection);
command.Parameters.AddWithValue("val1", "O'Hare");
command.Parameters.AddWithValue("val2", "O'Callahagan");
command.ExecuteNonQuery();
I am trying to log down sql that execute.
I have a function call LogGenerateReport(String Sql) that will do a insert process to save the data in a database.
The Problem i face is about the SQl ''.
For example:
INSERT INTO TABLE(Sql)
VALUE('SELECT * FROM Sales WHERE SalesID = 'ABC123';')
Its return me error and i know what happened because of the quote.
I try again inside my database where i open a new query and paste above sql and made some modification on it such as.
INSERT INTO TABLE(Sql)
VALUE('SELECT * FROM Sales WHERE SalesID = ''' + 'ABC123' + ''';')
Its return me expected result.
Output:
|Sql |
|SELECT * FROM Sales WHERE SalesID = 'ABC123';|
But back on my .aspx.cs page i have a string builder that store the executed query and before it executed, it need to save the query first.
For example:
System.Text.StringBuilder str = new System.Text.StringBuilder();
str.append("SELECT * FROM Sales WHERE SalesID = 'ABC123';");
api.LogGenerateReport(Convert.tostring(str));
Its return me error as like above because of the quote.
I try to figure it out to overcome this and my idea is
String TempSql = Convert.tostring(str);
TempSql.Replace("'","+'''");
I wont work because of the + symbol is at different position.
Is there any way to overcome this?
To succesfully log any and all SQL queries regardless of their content, you need to apply parameterized commands in the following way:
using(var command = new SqlCommand(someSqlConnection))
{
command.CommandText = "INSERT INTO TABLE(Sql) VALUE(#Sql)";
command.Parameters.AddWithValue("#Sql", "<any string>");
command.ExecuteNonQuery();
}
That way you can avoid escaping anything with NON-STANDARD methods, and protect your code from SQL injection attacks.
cmd.CommandType = CommandType.Text;
cmd.CommandText = #"SELECT * FROM Sales WHERE SalesID = #Param";
cmd.Parameters.Add("#Param", SqlDbType.Varchar).Value = 'ABC';
Try this out and using paramterised one is highly recommended and to some extent handling sql injection as well as these sorts of problems
Why can't you just replace all single quotes within the statement with double single qoutes?
This request works fine:
INSERT INTO TABLE(Sql)
VALUE('SELECT * FROM Sales WHERE SalesID = ''ABC123'';')
And the code:
String TempSql = Convert.tostring(str);
TempSql.Replace("'","''");
My guess is your api.LogGenerateReport isn't escaping single quotes when inserting the row into the database. You should fix your insert statement using paramaters.
To get it to "work" as is, you need to escape your single quotes with two single quotes. Try changing:
"SELECT * FROM Sales WHERE SalesID = 'ABC123';"
to
"SELECT * FROM Sales WHERE SalesID = ''ABC123'';" <-- these are 2 single quotes, no double quotes
Good luck.
Consider the following code:
SqlConnection conn = new SqlConnection(#"connection string");
SqlCommand ourCommand = new SqlCommand(String.Format(
#"SELECT Field1,Field2,Field3 FROM Tbl WHERE Field1 LIKE '#FL1'"), conn);
ourCommand.CommandTimeout = 6000;
ourCommand.Parameters.AddWithValue("#FL1", TextBox1.Text);
SqlDataAdapter adapter = new SqlDataAdapter(ourCommand);
DataTable dt = new DataTable();
conn.Open();
adapter.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
The problem is that datatable is empty - which means the command either was not executed or incorrect query was generated. What am I missing? Connection and query are valid. The command without parameter also works. Database engine is SQL Server 2008 R2
You've put the parameter name in quotes, so it's being treated as a value, not as a parameter. Try this instead:
"SELECT Field1,Field2,Field3 FROM Tbl WHERE Field1 LIKE #FL1"
(I'd actually expect your existing code to throw an exception given that you're supplying more parameters than are in the SQL...)
As noted in comments, you don't need the string.Format either.
Your query is not a well formatted query.
Instead of:
String.Format(
#"SELECT Field1,Field2,Field3 FROM Tbl WHERE Field1 LIKE '#FL1'")
Use:
"SELECT Field1,Field2,Field3 FROM Tbl WHERE Field1 LIKE #FL1"
Note that there is no need for string.Format, nor to enclose the parameter name in '' and since there is nothing to escape in the string, no need for it to be a verbatim string literal (using the #), as Jon commented.
Try changing the line to this (remove the tick marks sorrounding #FL1)
SqlCommand ourCommand=new SqlCommand(
"SELECT Field1,Field2,Field3 FROM Tbl WHERE Field1 LIKE #FL1",conn);
If you are using parameters, you don't need to use single quotes.
Take a look on lesson here.
Well, first, you don't need the string.format or the #'s (you have no escaped chars, your string are on one line, and you aren't using parameterized strings, so there's no reason for either one) Then, you don't need the quotes around #FL1. SqlCommand parses entire string for #'s, not for substrings delimited by quotes. The final code, I believe, should look like this:
SqlCommand ourCommand=new SqlCommand("SELECT Field1,Field2,Field3 FROM Tbl WHERE Field1 LIKE #FL1",conn);
Everything else I think you can keep the same.
You need to force concatenation with percent % ->
SELECT Field1,Field2,Field3 FROM Tbl WHERE Field1 LIKE **'%'** + #FL1 + **'%'**