Does Scala Anorm String Replacement Sanitize Inputs? - sql

I am using the Play! framework along with Anorm to access the database. I often see examples like the following where object members are injected into the SQL statement directly.
My question is, are these inputs sanitized? Most examples look like the following:
object Person {
def save(p:Person) {
DB.withConnection ("default") { implicit connection =>
SQL("""
INSERT INTO person(firstName,lastName)
values ({firstName}, {lastName})
"""
).on(
"firstName" -> p.firstName,
"lastName" -> p.lastName
).executeUpdate()
}
}
}
I will attempt to find out by way of hacking, but it's easy to make a mistake so I thought asking was more appropriate, and I can draw on the wisdom of the crowd.

According to its source code, Anorm builds onlyjava.sql.PreparedStatements, which prevent such SQL injection. (see the PreparedStatement wikipedia page for a general explanation)

Related

Kotlin - Inject Android Room SQL language on multiple line queries

How can I get multi-line queries to be injected? It works on Room with Java classes, but does Kotlin support this as well?
E.g. I have 2 queries here, and only the top SQL query (1 line) gets injected.
I tried to follow the steps in this guide but could not find the required settings.
There is an issue at https://youtrack.jetbrains.com/issue/KT-13636 which suggests this is fixed, but I'm not sure how to implement the fix.
You can use a raw string which is more readable anyway:
#Dao
interface ItemDao {
#Query("""
SELECT * FROM Item
WHERE Item.id = :id
""")
fun loadItemById(id: Long): LiveData<Item>
}

Using SQL instead of Linq to query database and return Json

I am developing an application using ASP.Net MVC and AngularJS. I am not familiar with linq and honestly I don't like it. But I am very familiar with SQL and I can perform complex queries. So, my question is, I want you to look at the below code from my MVC controller:
public JsonResult GetSupervisor()
{
var db = new scaleDBEntities();
return this.Json((from userObj in db.Users
select new
{
supervisorId = userObj.Id,
supervisorfName = userObj.usrFirstName,
supervisorlName = userObj.usrLastName,
})
, JsonRequestBehavior.AllowGet
);
}
How can I change the link query into SQL query?
I believe that I can do something like this:
var blogNames = db.Database.SqlQuery<string>("SELECT Name FROM dbo.Blogs").ToList();
So, if this is right, how can i use in in my return this.Json() for my angular?
Using the example you provided, something like this should work:
return this.Json(new {blogNames});
You're just creating an anonymously-typed object that the JSON serializer can use to produce an object like this:
{
"blogNames": ["blog one", "blog two"]
}
It'll be more complicated if you're trying to produce more complex results from a more complex query. But, well, that's what an ORM is for. I'd echo Gert Arnold's advice to embrace LINQ, rather than just deciding you don't like it because you're not used to it.

Uri.EscapeDataString Clarification Needed

I'm trying to sanitize data fields in order to prevent sql injections using ASP.NET and along the way have discovered Uri.EscapeDataString, which I believe is the solution(not sure). Here's my code, this is the execution page and Request[cur] is grabbing from an array "dictArr" which holds the names of my fields on the previous page.
foreach(string cur in dictArr) {
if(Request[cur] != "") {
dictionary[cur] = Request[cur].Trim();
}
index++;
}
To my understanding Uri.EscapeDataString makes the data nothing more than a string and is secure, no need to worry about a database wipe out. My question is, how do I use it? Am I doing it correctly below or is there another step I must take? Thanks
foreach(string cur in dictArr) {
if(Request[cur] != "") {
dictionary[cur] = Uri.EscapeDataString(Request[cur].Trim());
}
index++;
}
That's a bit different, you need to prevent attacks from the server point of view. If I was hacking I don't need to use your web site interface, I can POST whatever I like to your server.
That's a bigger concept but good to get across with the web.
There are a bazillion articles on the web about all that, e.g. http://en.wikipedia.org/wiki/SQL_injection
Start digging :)
Uri.EscapeDataString simply converts strings for safe transmission in a URL. Very much like Server.URLEncode, but with some differences.
I'm trying to sanitize data fields in order to prevent sql injections using ASP.NET and along the way have discovered Uri.EscapeDataString, which I believe is the solution(not sure)
No, this is not the correct way. Although encoding everything with EscapeDataString would encode inline SQL queries in a way that will avoid SQL injection, you will end up with URL encoded data in your database.
e.g. My name is O'Leary would be encoded as My name is O%27Leary
This would mean your application (and every other application now or in the future) will have to decode the data on every read. This is not standard and will add extra complexity to operations in future. For example, reading manipulating and writing data back to the database would have to be decoded, manipulated and then reencoded at the correct points.
The correct way to protect against SQL injection is to use parameterised queries.
String query =
"SELECT account_balance FROM user_data WHERE user_name = ?";
try {
OleDbCommand command = new OleDbCommand(query, connection);
command.Parameters.Add(new OleDbParameter("customerName", CustomerName Name.Text));
OleDbDataReader reader = command.ExecuteReader();
// …
} catch (OleDbException se) {
// error handling
}
This automatically protects against SQL injection as the parameters are treated as strongly typed values rather than part of the query structure.

Test for table/view existence with Scalaquery & create if not present

I am writing some tests to automate checking if a database (a MS SQL
Server instance) has certain views, and if it does not, creating those
views using the BasicTable object.
Something like:
#Test def CheckAndBuildViewsOnDB() = {
VerifyViewExists(FooTable, BarTable) //FooTable et al defined as:
FooTable extends BasicTable[Foo], where Foo is a case class & FooTable
has a DDL create defined.
}
Based on this and cribbing from Stefan Zeiger's assertTablesExist example, I made a little method to check the db for a view, and if the
check throws an exception call that view's BasicTable ddl.create:
def VerifyViewExists(views:BasicTable*) = {
DatabaseSession.session() withSession { //helper class which
initiates a db connection & session
views map {
v => (try queryNA[Int]("select 1 from '"+ v.tableName +"'
where 1<0").list
catch {case _: Exception => v.ddl.create;
println("Couldn't find view "+v.tableName+", creating it
now...");})
} } }
Which seems reasonable to me, but has two problems:
this isn't the right way to type the views parameter as BasicTable,
resulting in "error: class BasicTable takes type parameters"
something funky is happening with the map argument v's scope,
resulting in "error: value tableName is not a member of type parameter
T0".
Pardon my ignorance with this question, as I suspect that the root of
my issue lies with not understanding Scala's type system.
Along with those two problems is the nagging feeling that I haven't
really done VerifyViewExists in the most succinct or readable style.
Since you don't care what the type parameter is, you should be able to solve #1 by adding [_]:
def VerifyViewExists(views:BasicTable[_]*) = {
My guess is that fixing #1 will cause #2 to disappear.
By the way it may be better to write foreach rather than map, since the latter will collect the results into a new collection, which I don't think you want.

How do I wrap an EF 4.1 DbContext in a repository?

All,
I have a requirement to hide my EF implementation behind a Repository. My simple question: Is there a way to execute a 'find' across both a DbSet AND the DbSet.Local without having to deal with them both.
For example - I have standard repository implementation with Add/Update/Remove/FindById. I break the generic pattern by adding a FindByName method (for demo purposes only :). This gives me the following code:
Client App:
ProductCategoryRepository categoryRepository = new ProductCategoryRepository();
categoryRepository.Add(new ProductCategory { Name = "N" });
var category1 = categoryRepository.FindByName("N");
Implementation
public ProductCategory FindByName(string s)
{
// Assume name is unique for demo
return _legoContext.Categories.Where(c => c.Name == s).SingleOrDefault();
}
In this example, category1 is null.
However, if I implement the FindByName method as:
public ProductCategory FindByName(string s)
{
var t = _legoContext.Categories.Local.Where(c => c.Name == s).SingleOrDefault();
if (t == null)
{
t = _legoContext.Categories.Where(c => c.Name == s).SingleOrDefault();
}
return t;
}
In this case, I get what I expect when querying against both a new entry and one that is only in the database. But this presents a few issues that I am confused over:
1) I would assume (as a user of the repository) that cat2 below is not found. But it is found, and the great part is that cat2.Name is "Goober".
ProductCategoryRepository categoryRepository = new ProductCategoryRepository();
var cat = categoryRepository.FindByName("Technic");
cat.Name = "Goober";
var cat2 = categoryRepository.FindByName("Technic");
2) I would like to return a generic IQueryable from my repository.
It just seems like a lot of work to wrap the calls to the DbSet in a repository. Typically, this means that I've screwed something up. I'd appreciate any insight.
With older versions of EF you had very complicated situations that could arise quite fast due to the required references. In this version I would recomend not exposing IQueryable but ICollections or ILists. This will contain EF in your repository and create a good seperation.
Edit: furthermore, by sending back ICollection IEnumerable or IList you are restraining and controlling the queries being sent to the database. This will also allow you to fine tune and maintain the system with greater ease. By exposing IQueriable, you are exposing yourself to side affects which occur when people add more to the query, .Take() or .Where ... .SelectMany, EF will see these additions and will generate sql to reflect these uncontrolled queries. Not confining the queries can result in queries getting executed from the UI and is more complicated tests and maintenance issues in the long run.
since the point of the repository pattern is to be able to swap them out at will. the details of DbSets should be completly hidden.
I think that you're on a good path. The only thing I probaly ask my self is :
Is the context long lived? if not then do not worry about querying Local. An object that has been Inserted / Deleted should only be accessible once it has been comitted.
if this is a long lived context and you need access to deleted and inserted objects then querying the Local is a good idea, but as you've pointed out, you may run into difficulties at some point.