I am trying to build a website vulnerable to SQL injections (for educational purposes) with an ASP.NET API. To do that, I would like to call FromSql with a previously prepared SQL query as such:
String query = "SELECT * FROM users WHERE email = '"+email
+"' AND password = '"+password+"'";
return RepositoryContext.Users.FromSql(query).FirstOrDefault();
But this code will not compile as FromSql is expecting a FormattableString, and not a String. I get the following error message:
Error CS1503 Argument 2: cannot convert from 'string' to 'System.FormattableString'
The following would compile, but then this code would not be vulnerable to SQL injections anymore as Entity Framework will perform a prepared SQL query and convert email and password to SQL query parameters :
return RepositoryContext.Users.FromSql(
$"SELECT * FROM users WHERE email = {email}
AND password = {password}").FirstOrDefault();
Is there a way to convert a String to a FormattableString?
Thank you for your help.
What you see is Entity Framework doing a good job at preventing SQL injection by default.
You can teach SQL injection by using the FromSqlRaw method instead which takes a string that could be maliciously crafted.
See also Entity Framework Core SQL Queries → Passing parameters documentation:
Pay close attention to parameterization when using SQL queries
When introducing any user-provided values into a SQL query, care must be taken to avoid SQL injection attacks. SQL injection occurs when a program integrates a user-provided string value into a SQL query, and the user-provided value is crafted to terminate the string and perform another malicious SQL operation. To learn more about SQL injection, see this page.
The FromSql and FromSqlInterpolated methods are safe against SQL injection, and always integrate parameter data as a separate SQL parameter. However, the FromSqlRaw method can be vulnerable to SQL injection attacks, if improperly used. See below for more details.
Related
Scenario - in the application we are creating SQL statement dynamically.
string query = ”Select {0} from TABLENAME where {1}”;
string.Format(query, columnNames, whereClause);
These variable column names are coming from a third party service from our own domain. However, while running the fortify scan for this code, I am getting an error for SQL injection. The message says that the data columnNames is coming from the UNTRUSTED service. How do I handle this scenario?
My setup is similar to this for testing dapper calls for SQL Server using in-memory SQLite (http://mikhail.io/2016/02/unit-testing-dapper-repositories/) using this lib: https://github.com/ServiceStack/ServiceStack.OrmLite
I'm using dapper with ad hoc SQL for my DAL and wanted to test data access layer without dependency on SQL Server. I used SQLite in-memory database. Problem is SQL syntax are different between SQL Server and SQLite.
For example I have a query that returns paged results using offset and fetch next, but SQLite only supports limit and offset.
What if any suggestions you have for me to do my in memory unit test? I didn't go the EF route with mocked db context as dapper is more performant and didn't want to use stored procedures as I wanted to test my SQL as well. I'm not looking to mock my database calls.
Ormlite's Typed API is RDBMS agnostic so as long as you stick to OrmLite's Typed API you will be easily able to alternate between different databases by just changing the connection string and dialect provider, e.g:
//SQL Server
var dbFactory = new OrmLiteConnectionFactory(connectionString,
SqlServerDialect.Provider);
//InMemory Sqlite DB
var dbFactory = new OrmLiteConnectionFactory(":memory:",
SqliteDialect.Provider);
Then you can use either database to create, persist and query POCO's, e.g:
using (var db = dbFactory.Open())
{
db.DropAndCreateTable<Poco>();
db.Insert(new Poco { Name = name });
var results = db.Select<Poco>(x => x.Name == name);
results.PrintDump();
}
But if use the Custom SQL API's to execute MSSQL-specific SQL you wont be able to execute that against SQLite. You can make use of the mockable support in OrmLite, but I'd personally recommend sticking to OrmLite's RDBMS agnostic typed API's instead.
I am trying to put up a code to create a databases from my C# code (asp.net website).
This is my code:
SqlCommand myCommand = new SqlCommand("CREATE DATABASE #dbname", nn);
myCommand.Parameters.Add("dbname", dbname);
myCommand.ExecuteNonQuery();
nn.Close();
well, its not working. its giving me an error:
incorrect syntax near '#dbname'
BUT. if I won't use parameters, people can SQL inj to my database. do you have any idea how can use anything, to get the database name from a textbox. and that people can't SQL inj me database?
You can't use parameters in CREATE DATABASE or other DDL commands.
I'd suggest using SQL Server Management Objects instead of SQL
I am connecting to a Sybase 9 database to retrieve data. I can query the database without issue using ODBC connections but I am having an issue calling stored procedures. The procedure was written probably 6-7 years ago. This is what I have to execute the stored procedure.
OdbcCommand itemWeightAve = conn.CreateCommand();
itemWeightAve.CommandText = "ComputeLastCost";
itemWeightAve.CommandType = CommandType.StoredProcedure;
itemWeightAve.Parameters.AddWithValue("#OwnerId", "BananaHammock");//company number
itemWeightAve.Parameters.AddWithValue("#InventoryId", InventoryNumberHere);//inventory id from query results
itemWeightAve.Parameters.AddWithValue("#EndDate", EndDateHere);//end date from query results
OdbcDataReader itemAveReader = itemWeightAve.ExecuteReader();
I am not very familiar with Sybase or ODBC and the version these guys are using is extremely old and is no longer officially supported. Upgrading the Sybase database is out of the question. The error I get when attempting to execute this command is...
ERROR [42S02] [Sybase][ODBC Driver][Adaptive Server Anywhere]
Procedure 'ComputeLastCost' not found
I know that the procedure exists, it is typed correctly, and that the parameter names exist and are typed correctly. Does anyone have any tips/hints/suggestions for what I'm doing wrong here?
Turned the comment into an answer...
What is the default database of the login that you are using?
Is the stored procedure in the same database?
If not, you need to prefix your procedure name with the database name "sharedDB.ComputeLastCost".
You can check this by logging in with the same user/password through isql and try and exec it by hand. if you have to do a use database (ie. use database sharedDB) before you execute it, you need to put the db name in front.
You can also change your default database for the user. Either way should work.
I just realized if your C# application use LINQ-TO-SQL classes to interface with the database, you can your query like this
using (DatabaseContext context = new DatabaseContext())
{
context.Log = Console.Out;
var query = from Person p in context.People
where person.Name == "john"
select p;
Console.WriteLine(query.Name);
}
What is the equivalent in LINQ-TO-ENTITY (is this another name for ADO.NET?) for
context.Log = Console.Out
Or there is another way to see your actual SQL query to the database?
I always use SQL Profiler if you have MS SQL Server. What DBMS is this for? LINQ 2 Entities supports multiple DB types.
This also works...
var cust = (from c in context.Customers select c);
string sql = ((ObjectQuery)cust).ToTraceString();
From MSDN forums
Using EntityFrame 6 it is possible to just to a ToString() on your query at least when using MySQL
var cust = (from c in context.Customers select c);
string sql = cust.ToString();
As Greg in the comments notes, this gives you the parameterized query, so you will need to add in the values you want to use.
You can trace your SQL when using Linq2Entities
https://stackoverflow.com/questions/137712/sql-tracing-linq-to-entities
You may also want to look at this tool
Huagati Query Profiler
I believe the Tabular Data Stream (TDS) protocol used by Microsoft SQL Server sends commands and responses in plain text by default so unless you encrypt the connection between your SQL Server and the client, you should be able to view both the request and response with a comprehensive packet sniffer.
It will take some work but using a packet sniffer in this manner should allow you to see what T-SQL your LINQ is getting translated to.
Side Notes:
I recommend that you encrypt all communications between your client and SQL server unless both the client and server reside on the same machine and you are doing development testing.
If you can't risk using a decyrpted connection for testing purposes, your packet sniffer may have a plugin that will allow you to decrypt encrypted traffic, but I am not sure if there are any risks in using such a decryption plugin.
EF doesn't have a direct parallel to the stream based loging that LINQ to SQL uses. There are a number of profiling options available for a variety of costs. I've discussed some of these options at http://www.thinqlinq.com/Post.aspx/Title/LINQ-to-Database-Performance-hints. You can find a listing of these profilers and other LINQ tools at http://www.thinqlinq.com/Post.aspx/Title/linq-tools.