So I know that Rails helps protect against sql injections when used like this:
Object.find(:first, :conditions=>["name=?",name])
However, I can't seem to find if the autogenerated find_by and find_all_by methods protect agains sql injection.
i.e:
Object.find_by_name(name)
So these two calls have the exact same result. My question is even though the second one is more convenient, should I continue to use the first because it provides protection against sql injection, or does the second do that as well?
Yes, dynamic attribute-based finders (find_by_* family) do protect your app from sql injections.
Related
What is an example of an SQL injection attack for compromising the database?
What classes of SQL injection attacks cannot be prevented by the use of bind variables and why not?
How do bind variables help in preventing SQL injection attacks?
http://xkcd.com/327/
Speaking of native prepared statements - all the query literals which aren't supported (i.e. everything but simple strings and numbers) are obviously vulnerable, when not hardcoded.
https://stackoverflow.com/a/8265319/285587
1.:
Here's an example from the real world:
https://find-and-update.company-information.service.gov.uk/company/10542519
Since the company is still listed the attack seems to be unsuccessful as yet, however, in the case the injection succeeds in the future, I'll also include a screenshot.
Typically I use integer ids in my application, but for this one piece of dev I am doing look ups on a text field - a tag name.
I do make use of cfqueryparam but considering that it's a text field, could it be vulnerable to sql injection attacks, and if so, how do other people get around this other than tediously searching the string for SQL commands.
My query looks something like:
SELECT tagId -- etc etc
FROM tag
WHERE tagName = <cfqueryparam cfsqltype="cf_sql_varchar" maxlength="50" value="#arguments.tagName#" />
Thanks
That's safe by virtue of the fact that you're using <cfqueryparam>. That's what the tag does. It sends the value as text (or whatever the cfsqltype happens to be), not a command to be executed.
For the most part yes... doing sql injection for this would be very difficult. CFQUERYPARAM does make it almost impossible to sql inject a query. However, remember that nothing is 100% effective against all forms of attacks.
If you did not use cfqueryparam, then you would be vulnerable.
By using cfqueryparam you don't need to worry about SQL injection.
Try putting in injection attacks and see for yourself.
I've heard somewhere that using cfqueryparam together with Portcullis would be a stronger protection against XSS and block malicious hack attempts.
Most ColdFusion web developers are now finally using cfqueryparam, it
has taken about 10 years since that tag was introduced but I guess
better late than never. Keep in mind, that cfqueryparam prevents most
forms of SQL injection but not all. It also does nothing to cross-site
scripting (XSS) attacks. It doesn't matter how small your site is or
where it's hosted, it will experience these attack vectors. Portcullis
takes maybe 5 minutes to install and configure. Nothing is perfect,
but Portcullis has a solid track record - just google it. So, there's
simply no reason I can think of where a ColdFusion based site
shouldn't use it.
http://www.codfusion.com/blog/post.cfm/portcullis-2-0-released
Also, you may want to watch CFMeetup: Warning, your site is under attack presented by John Mason, the author of Portcullis.
When using ORM's (Entity Framework, LINQ to SQL, NHibernate ...), are SQL injection attacks mitigated by design?
If not, where should I be doing some extra validation/scrubbing to prevent a vulnerability?
Most, if not all, mainstream ORMs use parametrized SQL, which will protect you from a direct SQL injection attack. However parametrized SQL at the application layer will not protect you from latent SQL injection attacks. These occur when something down the line, other than the ORM, directly concatenates user input in a SQL statement (such as a batch run stored procedure that concatenates user input to create a non-parametrized dynamic query). Note that this isn't an ORM issue at all, but I thought I'd bring it up to point out that parametrized SQL only protects you from injections if it is used everywhere, not just in the ORM.
They are in NHibernate by using parameterized queries.
ORMs are designed to be secure, in the basic concepts. Most of the time you'll not have to worry about it, but if you think you might be exposed to real cracking you should do some custom tunning.
For simple apps, simple SQL injection you'll be cover. No body (seriously, no body ever) will give you a silver bullet in matters of security and SQL Injection. That's my advice.
ORMs typically use a lot of dynamic SQL, which is insecure because it gives users of the application and/or service accounts the ability to execute ad-hoc SQL queries. The correct solution is for only Programmers and DB Admins to have DataReader/DataWriter and all programs that touch the database to use nothing except parameterized Stored Procedures always with no DataReader/DataWriter access associated with the program. They can only access the SPs I say they can. Only the DB Admins and Programmers should be able execute ad-hoc SQL queries.
Plain-vanilla NHibernate setup, eg, no fluent NHibernate, no HQL, nothing except domain objects and NHibernate mapping files. I load objects via:
_lightSabers = session.CreateCriteria(typeof(LightSaber)).List<LightSaber>();
I apply raw user input directly to one property on the "LightSaber" class:
myLightSaber.NameTag = "Raw malicious text from user";
I then save the LightSaber:
session.SaveOrUpdate(myLightSaber);
Everything I've seen says that yes, under this situation you are immune to SQL injection, because of the way NHibernate parameterizes and escapes the queries under the hood. However, I'm also a relative NHibernate beginner so I wanted to double-check.
Thanks!
Yes, you're almost immune to SQL injection when using NHibernate. It uses parameterized queries for all generated SQL statements on all platforms that support these.
You can, however, circumvent this by using custom SQL for insertions/updates, or by executing SQL with a variation of execute_sql of some sort, or SQL Queries without parameters.
You're safe as long as you don't plug user input directly into HQL or SQL: nothing else (of the functionality hibernate provides) will allow users to inject malicious code.
Just to echo others, if you let NHibernate generate your SQL you're safe, at least in theory.
However, you still need to be careful with stored procedures, triggers, and functions in the database particularly with dynamic SQL. Even though the client uses parametrized queries everywhere, injection may still possible.
SO has plenty of Q&As about how to accomplish various tasks using dynamic SQL, frequently the responses are accompanied with warnings and disclaimers about the advisability of actually using the approach provided. I've worked in environments ranging from "knowing how to use a cursor is a bad sign" to "isn't sp_executesql neat!".
When it comes to production systems should dynamic sql always be avoided or should it have a valid place in the programming toolbox. If not/so, Why?
Answers to some of your questions can be found here The Curse and Blessings of Dynamic SQL
Sometimes you have to use dynamic SQL because it will perform better
It depends on what you mean by dynamic sql. Queries built where parameter values substituted directly into the sql string are dangerous and should be avoided except for the very rare case where there is no other option.
Dynamic SQL using the appropriate parameterized query mechanism supported by your platform can be very powerful.
There are several considerations when evaluating the use of dynamic SQL:
performance can vary widely, and specific to which database engine is targeted
maintenance can vary widely, in both directions (e.g., dynamic SQL can employ
modularization techniques that static SQL cannot)
dynamic SQL is vulnerable to SQL injection attacks, but static SQL is (mostly) not
sometimes your needs make static SQL (nearly) impossible, but that should be rare
Remember, SQL is code, and an RDBMS is another API. It is NOT special, or at least not much; deal with it like you would any other code and API. In particular, don't just code directly against the API: modularize your code and write some helper methods to make it easier and reusable.
The cost of 'dynamic SQL' varies between DBMS.
In IBM DB2, where query plans can be pre-compiled down to machine code, the cost of Dynamic SQL is significant.
In IBM Informix (IDS - Informix Dynamic Server), most queries are effectively 'dynamic SQL' (the exception is queries in stored procedures) in that the SQL is interpreted at run-time, even though the client-side notation uses static SQL.
I believe - though a DB2 expert might be able to contradict me - that the CLI (ODBC, aka CCC) and JCC (JDBC) systems for DB2 do all SQL as dynamic SQL.
I don't know what Oracle, Sybase, MS SQL Server do - my suspicion is that they hew closer to the line adopted by IDS than the line adopted by DB2. For MySQL and PostgreSQL, I'd be surprised if they did not behave more like IDS than DB2.
As a result, with IDS, there is no particular overhead to using Dynamic SQL; at the server level, your SQL is dynamic anyway. Other DBMS may have other factors at play.
One issue for all servers is 'how do you identify the pre-compiled query from the SQL sent over the wire'. With DB2, the pre-compilers identify the package which is used, and the communications protocol between application and server identifies that. My understanding is that the DB2 clients such as ODBC and JDBC do not use a pre-compiled package - hence I think that they effectively do dynamic SQL all the time.
Beware SQL injection with Dynamic SQL!
My previous shop would never allow such things to execute against the database (SQL Server).
It was prohibited as practice, and the DB was locked down to prevent it.
All work goes through objects (SPs, etc).
This is the right way to do it always, IMHO.
There are edge cases where dynamic SQL is both easier and faster than the alternative. As long as you keep them few and far between and they are dynamically generated prepared parameterized SQL I see no big problem with them.
Dynamic SQL has a place - even in production code. Executing arbitrary code with security holes does not.
In general, I would avoid using dynamic SQL if there is not a good reason to use it. Dynamic SQL does not get checked until it runs, so you obviously have a bigger testing burden. However, there are plenty of good times to use it when dealing with administrative tasks, static code-generation, accommodating changing systems without excessive maintenance based on querying metadata, using DRY to avoid redundancy, etc.
Our system has what I think is a lot of dynamic SQL in it, mostly because we have a lot of dynamically created objects (tables, indexes, views mostly). A lot of this is legacy; things like partitioned tables in 2k5 help somewhat in some of our use cases. But as mentioned you need to make a good case for it; on-the-fly SQL inside the procs usually has a better (static) solution.