C# sqlite injection [duplicate] - c#

This question already has answers here:
Avoiding SQL injection without parameters
(21 answers)
Closed 9 years ago.
If I change my select from
String insSQL2
= "select * from Produtos where nome = '" + txtBuscaNome.Text + "'"
To
String insSQL2
= "select * from Produtos where nome = ''" + txtBuscaNome.Text + "''"
Will it prevent sql injection?

No.
SQL injection isn't about creatively using quote characters. It's about treating input as data instead of as code. Take a look at a classic SQL injection vulnerability:
"SELECT * FROM Users WHERE Id = " + someValue;
It may intuitively look like you're using someValue as a data value, but you're actually using it as actual SQL code. The SQL engine doesn't see this as a value parameter, it sees it as part of the command being executed. That code should just be a value, but it can be anything. And you'd be executing whatever code is supplied.
Thinking of it in this way, it becomes clear that you should never execute user-supplied code in your application.
The alternative is to treat the user input as values in pre-defined code. That way you control the complete scope of the code and users are only supplying values. Which would look more like this:
"SELECT * FROM Users WHERE Id = #id";
Now the SQL engine sees that parameter (#id) and expects you to supply a value for that parameter. In ADO.NET it might look something like:
someCommand.Parameters.AddWithValue("#id", someValue);
Now the SQL engine knows that this is a data value and not code, so it treats it as data instead of executing it.

No, it won't prevent sql injection.
Use parameterized sql:
var insSQL2 = "select * from Produtos where nome = #nome";
var connection = new SqlConnection(/* connection info */);
var command = new SqlCommand(insSQL2, connection);
command.Parameters.AddWithValue("#nome", txtBuscaNome.Text);

Related

C# Command Parameters SQLServer [duplicate]

This question already has answers here:
A table name as a variable
(10 answers)
Closed 1 year ago.
I am building a sql query string like this:
var sqlDailyDataForOption = #"select underlying_symbol, quote_date
FROM [#val6]
Later I add the command line parameters thus:
command.Parameters.AddWithValue("#val6", o.underlying_symbol + "_1545");
I get an exception when I try to execute the query string:
using (SqlDataReader reader = command.ExecuteReader())
{
- $exception {"Invalid object name '#val6'."} System.Data.SqlClient.SqlException
However, if I hardwire the value o.underlying_symbol + "_1545" it works fine.
Is it that command-parameters can't be dynamically created in a FROM ?
You would have to use dynamic SQL and safely inject the value of the dynamic object into the statement. I'm not a C# developer, but I suspect it'll look something like this:
var sqlDailyDataForOption = #"DECLARE #SQL nvarchar(MAX) = N'SELECT underlying_symbol, quote_date FROM dbo.' + QUOTENAME(#var6) + N';'; EXEC sys.sp_executesql #SQL;"
command.Parameters.Add("#Var6", SqlDbType.NVarChar, 128).Value = o.underlying_symbol + "_1545"
try this
var val16=o.underlying_symbol + "_1545";
var sqlDailyDataForOption = $"select underlying_symbol, quote_date FROM [{val16}]";
but please remember about possibility sql script injection attack in this case and check val16 for malicious words like delete.

Setting SQL query parameter to Int32 in C#

I'm having problems with some code I'm trying to write. I'm doing something for suppliers orders, so I have a table which is named "encomendas_fornecedores" with a autoincrement field before the key that is the code of sale which consists in a EF before the number(which is a text field).
Here is the code:
connection.Open();
OleDbCommand comando1 = new OleDbCommand();
OleDbCommand comando2 = new OleDbCommand();
OleDbCommand comando3 = new OleDbCommand();
comando1.Connection = connection;
comando2.Connection = connection;
comando3.Connection = connection;
comando1.CommandText = "INSERT INTO encomendas_fornecedores (cod_encomenda_forn, cod_metodo, cod_forn, total_pagar_forn) VALUES('FO', '" + txtcodmetodo.Text + "', '" + txtcodforn.Text + "', '" + lbltotalapagar.Text + "'); ";// insert into table the values with a FO to cod
comando1.ExecuteNonQuery();
comando2.CommandText = "Select MAX(num_encomenda) From encomendas_fornecedores;";// selecting maximum num encomenda so I can isolate it and add to a text before(btw I do this in php/sql no problems
int numero = Convert.ToInt32(comando2.ExecuteScalar());//max num_encomenda
string codencomendaforn= "EF"+Convert.ToString(numero);// sales code completed
comando3.CommandText = "UPDATE encomendas_fornecedores SET cod_encomenda_forn = '"+codencomendaforn+"' WHERE num_encomenda = '"+ numero +"';";//query that is giving me the problems, it says something like "type of data incorrect in data expression"
comando3.ExecuteScalar();//giving me error this line
connection.Close();
But now here's the catch the cod_encomenda_forn is text and the num_encomenda auto increment as it is in the sql, and I tried to show the query in a textbox to see if its anything is wrong but nothing seems wrong.
"UPDATE encomendas_fornecedores SET cod_encomenda_forn = '"+codencomendaforn+"' WHERE num_encomenda = **'**"+ **numero** +"**'**;";//query that is giving me the problems,it says something like "type of data incorrect in data expression"
You are passing a string numero to a where statement that seems like it is expecting a number. As long as it is numeric it should work, but definitely not gauranteed to work. Second you are passing anothercodencomendaforn string to encomenda what is encomenda 's data type?
It appears that you are not handling potential datatype differences between your c# code and your SQL query. In addition single quoting '' around a value in a SQL statement tells the database engines that it is a string even if that is '1234'. While SQL will automatically convert some values it doesn't always. In addition c# .net library also looks for some conversion etc. before sending the SQL statement. To fix appropriately use parameters that are data typed to the database type in the SQL table. To fix it simply in the statement figure out your data types and fix the '' single quotes appropriately.
PS the people trying to help you in the comments were being nice and telling you the professional way of keeping your job in the future when you graduate after fixing this issue.

SQL Injection flaw

I am working on a project where the client has reported an SQL injection flaw in the code. Here is my codeā€¦
1 public int ExecuteNonQuery(string query, SqlParameter[] parameters)
2 {
3 using (SqlCommand command = CreateCommand(query, parameters))
4 {
5 int rowsAffected = command.ExecuteNonQuery();
6 return rowsAffected;
7 }
8 }
And the CreateCommand method goes as
private SqlCommand CreateCommand(string commandText, SqlParameter[] parameters)
{
SqlCommand retVal = this.connection.CreateCommand();
retVal.CommandText = commandText;
retVal.CommandTimeout = this.commandsTimeout;
retVal.Parameters.AddRange(parameters);
return retVal;
}
The flaw is reported at line number 3. I am unable to understand what kind of attack an happen here as this is a console application. But I have to fix the flaw and I don't know how to fix it.
Query is
#"delete from {0} where runId in
( select runId from {0}
inner join
( select sId as sId_last,
wfId as wfId_last,
max(runId) as runId_last from {0} where endTime is NULL
group by sId, wfId ) t1
on endTime is NULL and sId = sId_last and wfId = wfId_last
and (runId <> runId_last or startTime < #aDateTime)
)";
Help appreciated.
Thanks.
that code is injection-free... But note that the methods that call ExecuteNonQuery could build the query by composing strings.
An injection attack happens when you do something like:
string name = ...; // A name selected by the user.
string query = "SELECT * FROM MyTable WHERE Name = '" + name + "'";
so when you compose a query using pieces of text that are of external origin.
Note that a more subtle injection attack could be multi-level:
string name = // The result of a query to the db that retrieves some data
// sadly this data has been manipulated by the attacker
string query = "SELECT * FROM MyTable WHERE Name = '" + name + "'";
In general you don't need a user interface to cause an injection attack...
You could query something from a web site/from the db, and use the unsanitized result to query the db (as in the last example), causing an injection attack... Or even using the content of the configuration file could cause an injection attack: the priviledges needed to modify the configuration file could be different than the ones needed to do something on the DB, and a malicious user could have the priviledges to modify the configuration file but not have direct access to the DB. So he could use the program as a trojan horse against the DB.
about the query
The weak point of that query (that is a composition of strings) is in how the {0} is calculated. Is it a string chosen in a group of fixed strings? Something like:
string tableName;
if (foo)
tableName = "Foo";
else if (bar)
tableName = "Bar";
or is it something more user controlled?
If the table names are fixed in code, then there shouldn't be any injection attack possible. If the table names are "extracted" from some user input/some other table the user could have access, we return to the problem I showed before.
You've exposed a public method which can be accessed by any code that allows any SQL expression to be executed.
I would look at changing that method to being internal or private instead so that not just any code can call that method.
Line 3:
using (SqlCommand command = CreateCommand(query, parameters))
Both Query and parameters are available in this line.
SQL injection should not be prevented by trying to validate your input; instead, that input should be properly escaped before being passed to the database.
How to escape input totally depends on what technology you are using to interface with the database.
Use prepared statements and parameterized queries. These are SQL
statements that are sent to and parsed by the database server
separately from any parameters. This way it is impossible for an
attacker to inject malicious SQL.
Lesson on SQL injection for your reference.link2

Insert user defined variables in to the sql statements [duplicate]

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:

Update table according to row number in C# sql

I am writing a small program using an SQL database. The table name is StudentInfo.
I need to know the SQL code for the following
for (n=0; n<nRows; n++) {
string sql1="update StudentInfo set Position=" + n + " where <this has to be the row number>";
}
nRows is number of rows.
How can I get the row number for the above code?
best way to do this is to create a stored procedure in the database and use your code to pass the relevent information to the server
In order to accomplish this task you'll want to create a Stored Procedure or build a Query that actually accepts parameters. This will help you pass variables between, your method of concatenation will actually cause an error or become susceptible to SQL Injection attacks.
Non Parameter SQL Command:
using(SqlConnection sqlConnection = new SqlConnection("Database Connection String Here"))
{
string command =
"UPDATE Production.Product " +
"SET ListPrice = ListPrice * 2 " +
"WHERE ProductID IN " +
"(SELECT ProductID " +
"FROM Purchasing.ProductVendor" +
"WHERE BusinessEntityID = 1540);" +
using (SqlCommand sqlCommand = new SqlCommand(command, sqlConnection))
{
int execute = command.ExecuteNonQuery();
if( execute <= 0)
{
return false;
}
else
{
return true;
}
}
}
That method is essentially creation a connection, running our SQL Command, then we are using an integer to verify that it did indeed run our command successful. As you can see we simply using SQL to run our command.
The other important thing to note, you can't create a sub-query with an update; you have to create an update then run a select as the sub-query to hone in more specific data across so you can span across tables and so on.
The other alternative would be to use a parameter based query, where your passing variables between SQL and your Application.
I won't post code to that, because I believe you wrote the C# loop to demonstrate what you would like SQL to do for you. Which is only update particular rows; based on a specific criteria.
If you could post additional information I'd be more then happy to help you. But I'm just going to post what I believe you are trying to accomplish. Correct me if I'm wrong.

Categories