I have read about JPQL injection and SQL injection. In many sites it has been said that ORM injection is almost as same as SQL injection in a testers point of view. So what basically i want to know is the major differences between JPQL and SQL injections.
Both JPQL injection and SQL injection are examples of the broader category of Code Injection.
Any language that is parsed at runtime is susceptible to Code Injection.
JPQL or Java Persistence Query Language is similar to SQL in syntax, and in the fact that it is written as strings and parsed at runtime.
Building queries by passing JPQL query strings directly to the createQuery method, as shown above, is referred to in JPA as dynamic query construction because the query string can be built dynamically at runtime.
When the description says "built dynamically at runtime" they mean your code formats the JPQL query as a Java string, then submits the string to be parsed and executed. Therefore your code has an opportunity to combine fixed strings with variable content.
Here's an example of using parameters safely to combine a variable with a JPQL statement. This comes from https://www.objectdb.com/java/jpa/query/parameter
SAFE:
TypedQuery<Country> query = em.createQuery(
"SELECT c FROM Country c WHERE c.name = :name", Country.class);
return query.setParameter("name", name).getSingleResult();
Here's the same query written in an unsafe way, combining the variable directly into the string.
UNSAFE:
TypedQuery<Country> query = em.createQuery(
"SELECT c FROM Country c WHERE c.name = '" + name + "'", Country.class);
Don't use string concatenation to form JPQL queries if you can avoid it. That's how unsafe content sneaks into your JPQL.
Related
Our DBA don't want us to use double quoted fields and tables in our queries (don't ask me the reason)... the problem is that ServiceStack.OrmLite double quote them all, and I don't have any idea on how disable this behaviour. We are using ServiceStack.OrmLite Version 4.5.4.0.
For example:
public class ClassA {
public int ID {get;set;}
public string Name {get;set;}
}
If we make a simple query like:
using (IDbConnection db = dbFactory.Open())
{
return db.LoadSingleById<ClassA>(id);
}
would generate:
select "ID", "Name" from "ClassA" where "ID" = #0
And this is what our dba want:
select ID, Name from ClassA where ID = #0
If anybody could help, I would apreciate a lot
PS I know I can write myself all queries, but there are too much code to change, so I'm trying to avoid this solution because it's too much time consuming at the moment.
Based on my inspection of the source code, it appears that this cannot be changed out of the box.
When ORMLite builds its query, it grabs the column name and wraps it in quotation marks. See here: https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs#L384
An alternative would be to create a new OrmLiteDialectProvider that inherits whichever provider you are using (e.g., SQL Server, Oracle, etc), and override one of the following methods:
GetQuotedColumnName(string columnName)
GetQuotedName(string name)
Overriding either of those to exclude the quotation marks would get you what you're looking for.
Looking to perform a possible subselect in JPQL. I use SQL often and looking to perform a query like this:
Select ((Select SUM(e.hours.hours) from app$Time e
where e.type = 'Purchased')
-
(Select SUM(f.hours.hours) from app$Time f
where f.type = 'Used'))
I have not seen many examples of JPQL performing a query like this, hoping that this is possible.
Jay,
JPA 2.1 specification doesn't support subquery in the select list.
From the specification:
The SELECT clause can contain one or more of the following elements: an identification variable that
ranges over an abstract schema type, a single-valued path expression, a scalar expression, an aggregate
expression, a constructor expression.
Workaround: you can perform two JPQL queries and subtract the Used from the Purchased in the java code
Does Automapper works with IQueryable?
I have 2 Query
IQueryable<V_ImageUpload> Query1;
IQueryable<V_ImageUpload> Query2;
Mapper.CreateMap<IQueryable<V_ImageUpload_WithReceiptBackup>, IQueryable<V_ImageUpload>>();
Query1 = Mapper.Map<IQueryable<V_ImageUpload_WithReceiptBackup>, IQueryable<V_ImageUpload>>(Query2);
Exception occured is:
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary
I've not used AutoMapper (so this was an excuse to try it out!), but there are queryable extensions available. Both your queryables are of the same type, so I'm not exactly sure what you are trying to achieve, but perhaps something like this is what you want, which takes an IQueryable<V_ImageUpload_WithReceiptBackup> and converts it to an IQueryable<V_ImageUpload>:
IQueryable<V_ImageUpload_WithReceiptBackup> query1;
IQueryable<V_ImageUpload> query2;
// Only map the actual type, not the queryable types
Mapper.CreateMap<V_ImageUpload_WithReceiptBackup, V_ImageUpload>();
query2 = query1.Project().To<V_ImageUpload>();
The .Project().To<V_ImageUpload>() keeps it as IQueryable, while Mapper.Map would end up with a List/IEnumerable. I only tested this out with LINQ to Objects, but hopefully it works with Entity Framework, or whatever you are using.
Quick question... I have to work with quite a bit of legacy ASP code that I am cleaning up, and it all uses queries that are vulnerable to SQL injection. I have a library that I put together to replace them with parameterized queries, and I'm wondering if there is a difference from a security standpoint between the following approaches.
Approach 1: This is the approach shown on most examples where parameter objects are individually built and added to the Command object. Here's an example from another question.
Approach 2: Use the Command.Execute method with an array of parameter values. Example:
Command.CommandText = "select foo, bar from baz where a = ? and b = ?"
Command.Execute , Array(1, "BBB")
Yes, the first parameter to Execute is ignored.
The first approach has each parameter built with its type, size, etc all specified, and it needs to match the database. But I've always had trouble with that approach, weird errors and the like if everything isn't "just" perfect. So I prefer the latter, and it in fact works with my coding style much better because I can encapsulate the DB logic into a class and pass around arrays as needed without having to litter my code with tons of DB calls.
Example of approach #2 using my wrapper DB.Query method:
set rs = DB.Query("select foo, bar from baz where a = ? and b = ?", Array(1, "BBB")
Or:
set rs = DB.Query("select foo, bar from baz", empty)
(passing keyword empty to denote the parameter is not used)
Given that, I'm wondering: Is approach #2 still safe from SQL injection attacks?
Thanks.
Edit The call to Execute was wrong and written from memory, it has been corrected.
From my sight: yes it is.
i wrote a quick example and then debugged it with Visual Studio. After the call to
Command.Execute , Array(1, "BBB")
the Parameters object of the ADODB.Command is properly filled with the given values from the Array. The datatype and length of the parameters is correctly set.
So in my opinion this approach is as safe as the approach #1 (with a manually created Parameters object).
I need to query a table using FreeTextTable (because I need ranking), with SubSonic. AFAIK, Subsonic doesn't support FullText, so I ended up creating a simple UDF function (Table Function) which takes 2 params (keywords to search and max number of results).
Now, how can I inner join the main table with this FreeTextTable?
InlineQuery is not an option.
Example:
table ARTICLE with fields Id, ArticleName, Author, ArticleStatus.
The search can be done by one of more of the following fields: ArticleName (fulltext), Author (another FullText but with different search keywords), ArticleStatus (an int).
Actually the query is far more complex and has other joins (depending on user choice).
If SubSonic cannot handle this situation, probably the best solution is good old plain sql (so there would be no need to create an UDF, too).
Thanks for your help
ps: will SubSonic 3.0 handle this situation?
3.0 can do this for you but you'd need to make a template for it since we don't handle functions (yet) out of the box. I'll be working on this in the coming weeks - for now I don't think 2.2 will do this for you.
I realize your question is more complex than this, but you can get results from a table valued function via SubSonic 2.2 with a little massaging.
Copy the .cs file from one of your generated views into a safe folder, and then change all the properties to match the columns returned by your UDF.
Then, on your collection, add a constructor method with your parameters and have it execute an InlineQuery.
public partial class UDFSearchCollection
{
public UDFSearchCollection(){}
public UDFSearchCollection(string keyword, int maxResults)
{
UDFSearchCollection coll = new InlineQuery().ExecuteAsCollection<UDFSearchCollection>("select resultID, resultColumn from dbo.udfSearch(#keyword, #maxResults)",keyword,maxResults);
coll.CopyTo(this);
coll = null;
}
}
public partial class UDFSearch : ReadOnlyRecord<UDFSearch>, IReadOnlyRecord
{
//all the methods for read only record go here
...
}
An inner join would be a little more difficult because the table object doesn't have it's own parameters collection. But it could...