I would like to make sure when using SqlCommand that I am using best practices, particularly with regards to security.
Considerations that I am not sure about:
Is it ok to manually build the string by appending? If not, how should I do it?
What classes should I be looking at using instead?
If your first question is talking about building SQL by including the values directly, that's almost certainly not okay. It opens you up to SQL injection attacks, as well as issues with conversions (e.g. having to get the right date/time format).
Instead, you should use a parameterized query, and set the values in the parameters. See the docs for SqlCommand.Parameters for an example.
Out of interest, do you have a particular reason for using SQL directly instead of using one of the many ORMs around? (LLBL, Entity Framework, NHibernate, LINQ to SQL, SubSonic, Massive, SimpleData, Dapper...)
I would say use of parameters is one of the most important aspects for security. This will prevent SQL Injection into your database. The following SQLCommand is an example of how I would construct one (in VB.NET, apologies - no C# knowledge - yet ;))
Dim cmd as New SqlCommand("sp_StoredProcedure", Conn)
cmd.commandType = commandtypes.storedprocedure
cmd.parameters.add("#ID",sqldbtype.int).value = myID
cmd.executenonquery
And an example of an inline SqlCommand:
Dim cmd as New SqlCommand("SELECT Name, Message FROM [Table] WHERE ID=#ID", Conn)
cmd.commandType = commandtypes.storedprocedure
cmd.parameters.add("#ID",sqldbtype.int).value = myID
cmd.executenonquery
My advice: be lazy. Writing voluminous code is a good way to make brain-dead errors (wrong data type, null checks, missing Dispose(), etc), and it has zero performance advantage over many of the helper tools.
Personally, I'm a big fan of dapper (but I'm somewhat biased), which makes things easy:
int customerId = ...
var orders = connection.Query<Order>(
#"select * from Customers where CustomerId = #customerId",
new { customerId });
Which will do parameterisation and materialisation for you without pain, and stupidly fast.
For other scenarios, and in particular when you want to use OO techniques to update the system, an ORM such as EF or L2S will save you work while (and giving you better type-checking via LINQ).
I think this is the best solution
SqlConnection cn = new SqlConnection(strCn);
try
{
using (SqlCommand cmd = new SqlCommand("select * from xxxx", cn))
{
cn.Open();
//do something
cn.Close();
}
}
catch (Exception exception)
{
cn.Close();
throw exception;
}
Depending, when I do POC or personnal small projects I normally build my strings manually but when im in a project for work we have a template for DB usage and connection that I must use and can't reveal here obviously.
But I think it's ok to manually build for basic operations in small project or POC.
Edit : Like Jon said though you should always use somehting like SqlCommand.Parameters when building your own command. Sorry if I wasn't clear.
If you're concerned about security, I recommend create your queries as Stored Procedures inside the SQL Server Database instead (to prevent worrying about SQL injection), and then from the front end code, just generate a SQL Stored Procedure, add the parameters, and do it that way.
This article should help you out with setting this up.
You should always use the practice of applying the least privileges to database connections by communicating with the database through stored procedures.
Store Procs
using System.Data;
using System.Data.SqlClient;
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet userDataset = new DataSet();
SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
myCommand.SelectCommand.Parameters.Add("#au_id", SqlDbType.VarChar, 11);
myCommand.SelectCommand.Parameters["#au_id"].Value = SSN.Text;
myCommand.Fill(userDataset);
}
The credentials for the connection string to the database:
A. Integrated Security for corporate/intranet
B. Keep it encrypted in the registry or a file in Hosting Providers.
Always be on the lookout for hackers trying to upload cross scripting into your forms.
Always check the input for SQL injection.
Related
I am working on a .net website which uses a DB2 database which uses Insert/Update and Select Queries. I researched about SQL Injection and I believe I've parametrized my query to avoid SQL Injection. Could you check if I've done it correctly and is there a better way or more sufficient way of doing it?
strInsert = "INSERT INTO DATABASE.Table(NUMBER,SIGNATURE,MESSAGE,CDATE,CTIME) VALUES (?,?,?,?,?)";
DB2Command cmdInsertQuery = new DB2Command(strInsert, db2Connection1);
cmdInsertQuery.Parameters.Add("NUMBER", i);
cmdInsertQuery.Parameters.Add("SIGNATURE", strSignature.Trim());
cmdInsertQuery.Parameters.Add("MESSAGE", strMessage.Trim());
cmdInsertQuery.Parameters.Add("CDATE", DateTime.Now.ToShortDateString());
cmdInsertQuery.Parameters.Add("CTIME", DateTime.Now.ToShortTimeString());
cmdInsertQuery.ExecuteNonQuery();
The query inserts the data correctly and works fine.
Yes, you have done it correctly. Good to know you are aware of SQL injection problems and trying ways to eradicate it.
add is deprecated use addwithvalue, it still almost does the same thing as add but my visual studio always cries about it
Example
string insertStatement =
"Insert Login VALUES(#username,#password,#publicKey,#privateKey,#salt)";
SqlCommand insertCommand = new SqlCommand(insertStatement, connection);
insertCommand.Parameters.AddWithValue("#username", username);
and is there a better way or more sufficient way of doing it?
one of options is to use
https://github.com/StackExchange/dapper-dot-net
Basically I have a website that I am working on where there will be over 8 listboxes filled with information from databases. I currently use SqlDataSource because of ease of use and am using it currently databound to the listboxes.
Does SqlDataSource leave the connection open the whole time? I want to eliminate from an website architectural standpoint any unnecessary continuously open connections for security reasons as well as performance reasons.
Directly in answer to your question: No. The SqlDataSource control ensures that the connection is closed as soon as the operation it is required to perform has been completed.
I used to use SQLDataAdapter + SQLCommand, but now I mostly use
using(SQLDataReader rdr = <YourSQLCommandVariable>.ExecuteReader())
{
rdr.Load(<YourDataTableVariable))
}
Reason being I was unsure what data adapter did on top of the data reader to allow it to do batches of updates, reads and deletes. If you think about it, it would be extremely difficult to write a class like the data adapter that can do all that, without introducing any overhead. The overhead may not be significant, but unless I'm reading multiple tables out of a query into a DataSet object I don't run the risk of using it.
All that being said, I doubt any overhead on these operations is worth even considering if you locally cache all of the resulting data into the local machine. In other words, the biggest improvement you can make to your SQL queries is to not make them if the data is not likely to change over some time frame. If the data is updated once a day, cache it for 24 hours or less. Caching can be done either via the Session if it is end-user-dependent or via the HttpContext.Current.Cache object.
It sounds like you might want some tier separation in your application. The Web project is ideally ignorant of the database. Ideally there is some middle tier assembly that handles communicating with the database. Then from your .aspx.cs or Controller,depending on whether or not you're using MVC, you would make 8 calls to the middle tier (one for each listbox assuming they have distinct information). The middle tier would return something like List<MyObject> which you would then bind to the listbox.
My typical pattern for data access looks like this
using (SqlConnection conn = new SqlConnection("conn string"))
{
conn.Open();
SqlCommand command = new SqlCommand()
{
CommandText = "command text",
Connection = conn,
CommandType = CommandType.StoredProcedure //could be non-stored proc.. but would reccomend stored proc assuming SQL Server
};
command.Parameters.Add(new SqlParameter("MyParam", "param1"));
command.Parameters.Add(new SqlParameter("MyParam2", "param2"));
IDataReader reader = command.ExecuteReader();
while(reader.Read())
{
//magic here
}
conn.Close();
}
everyone I am a student and new to .NET and specially MVC3 development but for one of my project I’ve to work over it and so going through the learning phase
Issue and confusion I am facing is regarding DB-Connectivity, whast I leanree d regarding retrieving records from a database is something like this:
//Method One:
var conn = new SqlConnection(conString.ConnectionString);
const string cmdString = "Select * FROM table";
var cmd = new SqlCommand(cmdString, conn);
var mySqlDataAdapter = new SqlDataAdapter(cmd);
mySqlDataAdapter = new SqlDataAdapter(cmd);
mySqlDataAdapter.Fill(myDataSet, "design");
// making a new SqlCommand object with stringQuery and SqlConnection object THEN a new SqlDataAdapter object with SqlCommand object and THEN filling up the table with the resulting dataset.
But while I was checking out MSDN Library i found out that SqlDataAdapter offers a constructors SqlDataAdapter(String, String) that directly takes a SelectCommand and a connection string to initiate thus skipping the role of SqlCommand in between, like this:
//Method Two:
var conn = new SqlConnection(conString.ConnectionString);
const string cmdString = "Select * FROM table";
var mySqlDataAdapter = new SqlDataAdapter(cmdString, conn);
mySqlDataAdapter.Fill(myDataSet, "design");
Looks short and pretty to me, But I am confused here that if this is possible in this way then why most of the books/Teachers goes by earlier (SqlCommand’s way).
What’s actually the difference between SqlCommand and SqlDataAdapter?
Which method is better One or Two?
Am afraid of I am using a shortcut in method two that could affect security or performance wise?
Apologising in advance if I sound very newbie or blurred! Will appreciate any help that could clear my concepts up! Thankyou! :)
Errorstacks summed it right:
SqlAdapter is used to fill a dataset.
SqlCommand can be used for any purpose you have in mind related to Create/Read/Update/Delete operations, stored procedure execution and much more.
In addition:
SqlCommand CAN have one big advantage against usage of raw strings in regards of security - they CAN protect you from Sql Injections. Just use parameters for values provided by the user instead of string.Format(...).
My personal preference is to wrap ANY sql strings in SqlCommand and add SqlParameters to it in order to avoid Sql Injection by malicious users.
Regarding performance of the two approaches - I don't expect that there is any difference. (If someone can prove me wrong - do it!).
So I would suggest to stick with the longer variant 1 and use commands plus parameters if necessary.
A bit of a side note - Datasets and DataTables are a bit out of game recently due to Linq2Sql and Entity Framework.
But of course the knowledge of plain old SqlCommands/Adapters/Readers is welcome :)
Hurry-up! Turn your attention to LINQ!!!
No more gran'ma stuff like SQLDataset or TableAdapters, no open connection.
Everything gets smoother with LINQ.
LINQ sample:
dim result = from emp in myDataContext.Employees
where emp.Salary > 10000
Select emp.ID, emp.SurName, ....
myDatagrid.datasource = result.toList
With LINQ, you don't have to worry about single quotes or crlf within your queries...
And you'll even have intellisense on the SQL tables, columns and objects!
I'm using Microsoft Visual C# 2008 Express Edition with SqlLite. I'm successfully able to open my database and with C# code, add entries to my tables.
When it comes to retriving data, I'm having some issues and have been searching and searching the internet for basic tutorial information on how to do these basic things...
Here's my code... (after I've opened up a connection to the database which is called 'conn' here):
SQLiteCommand cmd = new SQLiteCommand(conn);
cmd.CommandText = "select myField1,myField2 from myTable where myField3 = '" + tempstring + "';";
cmd.CommandType = CommandType.Text;
SQLiteDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
string tmp = reader.GetString(0);
System.Console.WriteLine(" my output = " + tmp);
}
When I execute this... I get no errors and because I get no output on that last line, it looks like the while loop is not executing at all.
I'm a beginner to this stuff... what am I missing and is there a good web resource where I can learn these basic things? I'm pretty comfortable in SQL on it's own... just not integrated in C# like this...
First, remove the hurtful trailing semicolon from the line while (reader.Read());...!
This looks correct to me. Does the property reader.HasRows return true for your query?
A couple of side issues to be aware of are:
Be sure to dispose of your SQL resources by wrapping your objects in using { } blocks.
Consider using parameterized queries instead of injecting the query parameter directly in the SELECT statement.
Answering your question on how to write parameterized queries:
cmd.CommandText = "select myField1,myField2 from myTable where myField3 = #tempString;";
SQLiteParameter param = new SQLiteParameter("#tempString");
cmd.Parameters.Add(param);
// you can modify that value without touching the sql statement (which means you could cache the above command)
param.Value = tempstring;
SQLiteDataReader reader = cmd.ExecuteReader();
[...]
Parameters in SQLite can have several forms which you can find here.
See here for more info on parameterized queries.
Good one, Alex.
In addition to that and since you are beginning with sqlite (you may want to delete second L from the tag), remember that sqlite does not really guaranty data type safety on the database level.
Not to divert you from your Sqlite question, but if you are having comfort issues with Sqlite queries embedded in C#, you could try NHibernate coupled with Fluent NHibernate. These technologies provide an excellent data access mechanism into databases, including Sqlite.
NHibernate requests into Sqlite are very fast, and you won't have to worry about some of the Sqlite idiosyncrasies. If you build out your data-access layer properly with NHibernate, you should be able to up-scale to a more robust database very quickly.
I know there have been numerous questions here about inline sql vs stored procedures...
I don't want to start another one like that! This one is about inline (or dynamic) sql.
I also know this point has become more or less moot with Linq to SQL and its successor Entity Framework.
But... suppose you have chosen (or are required by your superiors) to work with plain old ADO.NET and inline (or dynamic) sql. What are then the best practices for this and for formatting the sql?
What I do now is the following:
I like to create my SQL statements in a stored procedure first. This gives me syntax coloring in SQL Server Management Studio and the ability to test the query easily without having to execute it in code through the application I'm developing.
So as long as I'm implementing/debugging, my code looks like this:
using (SqlConnection conn = new SqlConnection("myDbConnectionString"))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "myStoredProcName";
// add parameters here
using (SqlDataReader rd = cmd.ExecuteReader())
{
// read data and fill object graph
}
}
}
Once the debugging and testing phase is done, I change the code above like this:
using (SqlConnection conn = new SqlConnection("myDbConnectionString"))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = GetQuery();
// add parameters here
using (SqlDataReader rd = cmd.ExecuteReader())
{
// read data and fill object graph
}
}
}
And I add an extra private method e.g. GetQuery() in which I copy/paste the whole block of the stored procedure like this:
private string GetQuery()
{
return #"
SET NOCOUNT ON;
SELECT col1, col2 from tableX where id = #id
-- more sql here
";
}
Working like this has the benefit that I can revert the code easily to call the stored procedure again if I have to debug/update the sql code later, and once it's done I can easily put the sql code back with copy/paste, without having to put quotes around every line and stuff like that.
Is it good practice to include newlines in the query?
Are there other things or tricks that I haven't thought of which can make this approach better?
How do you guys do things like this?
Or am I the only one who still uses (has to use) inline sql?
Inline (with or without the literal #"..." syntax) is fine for short queries... but for anything longer, consider having the tsql as a file in the project; either as embedded resources / resx, or as flat files. Of course, by that stage, you should probably make it a stored procedure anyway ;-p
But having it as a separate file forces the same separation that will make it a breeze to turn into a stored procedure later (probably just adding CREATE PROC etc).
One issue with inline - it makes it so tempting for somebody to concatenate user input... which is obviously bad (you've correctly used parameters in the example).
I've used .NET resource files in the past. These were handy for keeping a library of all queries used in a particular code library, particularly when the same query might be used in multiple places (yes, I realize this also indicates some poor design, but sometimes you need to work within the box given to you).
Beyond non-trival single-line SQL statements, I always take advantage to multi-line and make it a const
const string SelectMyTable = #"
SELECT column_one
, column_two
, column_three
FROM my_table
";
This all allows me to cut and paste to SQL manager for testing.