Under what circumstances will nhibernate run queries without parameters? - sql

During a pen-test of an in-development app, I had a scary result where there was a successful SQL injection due to NH executing a query without parameters and instead injecting a string right into the query.
We're using NHibernate 4 and Fluent NHibernate 1.4. Dialect is SQL 2008 running against SQL Azure.
The successful query looked like this (pulled from SQL Azure audit logs)
select columns from [Table] table0_ where table0_.TenantId='1555%00';IF(5672=5672) SELECT 5672 ELSE DROP FUNCTION GziQ--' and table0_.Active=1
As you can see, the injectable string was able to terminate the string and inject a DROP FUNCTION then comment out the rest of the statement.
Running this locally and using NHibernate Profiler, we see the value being passed as a parameter as-expected:
select columns from [Table] table0_ where table0_.TenantId = #p0 and table0_.Active=1
On the code side, the data is queried using an IQueryable interface (code inlined and simplified for example purposes):
Session.Query<TEntityType>().Cachable().Table.SingleOrDefault(k => k.TenantId == tenantId && k.Active);
Under what circumstanes would NHibernate not parameterize this query and instead inject the string directly into a plain SQL statement?

Related

JPA Query - sql injection in positional parameters jpa native query

As I read in a lot of articles, when I use JPA/Hibernate query it is good to set parameters in my queries so SQL injection is avoided. Like:
select user from User user where user.name = :name and user.surname = :surname
My problem is that in some cases I need to use native query when I create my query.
I will use my entity manager and createNativeQuery. But in this case the parameters will be positional. Like:
select * from users where user_name = ? and user_surname = ?
Then in my query I will use the method setParameter(1, "name") etc. So is this case "sql injection proof" like when in the parameterized query?
if you do not use string operations for building your query like
"SELECT foo FROM bar Where id="+myParameter+" more sql ..."
, then you will not have any vulnerabilities.
Currently (community correct me if I am wrong) no vulnerabilities exist within the latest PDO database abstraction layer.
However testing your queries for known and unknowns while sanitizing and filtering input will help eliminate the possibility of an injection in the event of a zero day exploit.
I currently use a combination of filtering input, charset expectations, stored procedures and strict requirements on their arguments prior to any and all dynamically created queries

NHibernate show-sql - why is the SQL shown invalid?

I love the feature in NHibernate that shows the generated SQL. But when I pasted it into SQL Server Management Studio, I realised it's not actually valid!
Here's an example:
SELECT person0_.PersonId as PersonId1_0_, person0_.Title as Title1_0_, person0_.FirstName as FirstName1_0_, person0_.MiddleNames as MiddleNa4_1_0_, person0_.LastName as LastName1_0_ FROM Kctc.People person0_ WHERE person0_.PersonId=#p0;#p0 = 1
This is not valid because of the way the parameter p0 is specified. It needs:
DECLARE #p0 int
SET #p0 = 1
before the SELECT command.
I guess my question is: why does NHibernate not show the ACTUAL SQL it sends to the database? Why does it show this instead?
Is there something I'm missing?
Thanks
David
The command sent to SQL Server is sent is a string argument to the sp_executesql system stored procedure. The parameters list is sent as a list of parameter, value pair arguments. You can easily see this using SQL Profiler. NHibernate Profiler reformats the query into one you can cut and paste into SSMS.
Here's an example of an actual NHibernate object load as sent to SQL Server:
exec sp_executesql N'SELECT track0_.TrackId as TrackId84_0_, track0_.CreatedBy as CreatedBy84_0_, track0_.CreatedDt as CreatedDt84_0_, track0_.RevisedBy as RevisedBy84_0_, track0_.RevisedDt as RevisedDt84_0_, track0_.Name as Name84_0_, track0_.Description as Descript7_84_0_ FROM Nucleus.Track track0_ WHERE track0_.Name=#p0',N'#p0 nvarchar(8)',#p0=N'6036HPGP'
Since the query is sent as a string to sp_executesql, you may get an execution plan that is different than the one generated by executing the query directly. In some cases this can be a huge performance hit.
The SQL is sent to the driver as a prepared statement, either the SQL driver takes care of assembling the final SQL or the parameters are sent seperatly to the server in case of a server side prepared statement - neither of which hibernate has much control over, or any way of pulling back the final SQL after it's sent down to the driver.
hibernate is just showing you that parameterized SQL as well as the value of #p0 that it hands off to the SQL driver.

NHibernate Lambda expressions - are they turned into SQL

I'm a bit of a NHibernate newbie and Im taking on some code written by another developer. I want to find out how NHibernate converts lambda based criteria into SQL.
I know in Linq to SQL using Lambda expressions on queries means that the whole thing is turned into an expression tree and then into SQL (where possible) by the Linq to SQL provider. This can be seen by doing DataContext.Log = Console.Out.
But what about an NHibernate criteria expression where Linq to NHibernate isnt being used?
The following namespaces are imported...
using NHibernate;
using NHibernate.Criterion;
using NHibernate.LambdaExtensions;
.. and the criteria code looks like this...
return Session.CreateCriteria<MyObjectType>()
.Add<MyObjectType>(x => x.Id == id)
.UniqueResult<MyObjectType>();
Will this be turned into an SQL statement e.g.
Select distinct * from table where id = [param]
... or will the whole dataset be pulled into memory giving a List and then have the lambda expressions applied against the objects. e.g.
return List<MyObject>.Where(x => x.id = id) [or something similar].
I', not sure if my importing NHibernate.LambdaExtensions provides a sort of translation into SQL.
It is turned to an HQL statement first (enable logging and look at the console for the statements) and then to an SQL and sent to the database.
It does not select the whole table to memory and filters there.

LINQ-to-SQL IN ()

Currently I use a block of code like this, to fetch a set of DB objects with matching IDs.
List<subjects> getSubjectsById(List<long> subjectIDs){
return ctx.tagSubjects.Where(t => subjectIDs.Contains(t.id)).ToList();
}
But this is really inefficient, because it requires the entire table to be read from the database and then filtered inside of C#.
What I would rather do would be something the equivelent of:
SELECT * FROM subjects WHERE subjects.id IN (1,2,3,4,5,...);
The big difference is that in the first example the filtering is happening inside the C# code, and in the second the filtering is done on the SQL server (where the data is).
Is there a [better] way to do this with LINQ?
Where did you find out that it downloads the entire table from SQL Server?
I'm sure it does what you want. It translates the query to a parameterized IN clause like:
... IN (#p1, #p2, #p3)
and passes the contents of the list as values to those parameters. You can confirm this with tools such as SQL Profiler and LINQ to SQL debugger visualizer or set the DataContext.Log property to console (before executing the query) and read the generated SQL:
dataContext.Log = Console.Out;

NHibernate createQuery with colons from method cal

I get a Antlr.Runtime.NoViableAltException thrown when trying to run the following query in NHibernate.
IQuery query = session.CreateQuery("from <table> where 1 in (select <column>.STIntersects(geography::STGeomFromText('POINT(:longitude :latitude)', 4326)))");
I'm setting longitude and latitude in setQuery.
my assumption is the :: in calling geography::STGeomFromText... because it's thinking it's a query parameter. Is there a way to escape the :?
This query works in my SQL Manager Studio.
Thanks!
Does NHIbernate support the STIntersects method ?
What you could do, is let NHibernate execute a (native) SQL query, like this:
ISQLQuery query = session.CreateSQLQuery ("your sql statement goes here");
query.AddEntity (typeof(TheEntityTypeThatYouWant));
var result = query.List<TheEntityTypeThatYouWant>();
See this post for some more info: Using SQL Server 2008 Geography types with nHibernate's CreateSQLQuery
Just to share what I ended up doing was taking the ADO connection out of the NHibernate session, performing a SqlCommand directly and manually built my Model objects from the results. It sucks, but it works. The connection still managed by NHibernate correctly.