rails: does the build method protect against sql injection - sql

Does build protect against sql injection?
Example:
#post = #user.posts.build(params[:post])
#post.save
Didn't see build in the rails security docs.
Thanks!

build itself doesn't write anything to the database so SQL injection doesn't apply. When you call save it doesn't matter whether the object was created via build or via another mechanism such as passing attributes to new or using individual attribute= methods, the same code will be used to save your object to the database.
From the documentation on build:
Returns a new object of the collection
type that has been instantiated with
attributes and linked to this object
through the join table, but has not
yet been saved.
The save method will escape any quotes etc in your attribute values using a method appropriate to the database you're using (e.g. MySQL) so that the resulting insert or create query is not susceptible to SQL injection. The same applies to update_attributes and to any parameterised :conditions that you pass to find. The time when you need to be careful and may need to do some manual escaping is if you are ever passing literal strings to the database connection as queries.

Related

Is String.sanitize, the best way to protect from SQL injection in rails or sinatra apps

Is string.sanitize the best way to protect from sql injection.
Do we need to install the Sanitize gem for it
or is there a better way?
value = "O'Brian"
value.sanitize =>"O\'Brian"
or
value.escape =>"O\'Brian"
It s probably included by default in Rails 5 , but what about using sinatra.
To protect against SQL injections, you should us prepared statements. About all high-level database adapters offer capabilities to use and properly escape variables. In ActiveRecord, this looks like this:
value = "O'Brian"
Person.where(name: value).to_sql
# => "SELECT `people`.* FROM `people` WHERE `people`.`name` = 'O\\'Brian'"
Other database adapters like Sequel or DataMapper have similar capabilities.
When using a plain database adapter like pg or mysql2, you can use plain prepared statements on the database level.
With mysql2, this can look like this:
value = "O'Brian"
statement = #client.prepare("SELECT * FROM people WHERE name = ?")
result = statement.execute(value)
Alternatively, all adapters offer database-specific string escape methods. But you should generally stick to prepared statements as they are safer to use when you just don't attempt to reason about escaping but delegate all of this to a library which does this consistently.
As a final note about the sanitize method and the sanitize gem, they are not intended for escaping SQL fragments and won't save you from SQL injections when used that way. The sanitize gem is used to ensure that HTML code only contains safe whitelisted tags and attributes. It has nothing to do with escaping SQL and will result in vulnerable code if used that way!

Logging the SQL generated by LINQ to SQL in Entity Framework in .net

I am designing a testing framework that makes extensive use of SQL Sever Database. I am using Entity Framework 6 of .NET to felicitate it. I want to log the Underlying SQL query each time when I run a test case. I am using LINQ to SQL for querying Database.
I am having a hard time logging the SQL. LINQ to SQL generates some uncooked SQL which needs to be converted into SQL by filling in the parameters which I want to avoid.
Is there a better approach which will log all the SQL which I can directly feed to my SQL Server without doing any changes in Query ?
According to Entity Framework Logging:
The DbContext.Database.Log property can be set to a delegate for any method that takes a string. Most commonly it is used with any TextWriter by setting it to the “Write” method of that TextWriter. All SQL generated by the current context will be logged to that writer. For example, the following code will log SQL to the console:
using (var context = new BlogContext())
{
context.Database.Log = Console.Write;
// Your code here...
}
in the above way you should be able to log everything.
The following gets logged:
When the Log property is set all of the following will be logged:
SQL for all different kinds of commands. For example:
Queries, including normal LINQ queries, eSQL queries, and raw queries from methods such as SqlQuery
Inserts, updates, and deletes generated as part of SaveChanges
Relationship loading queries such as those generated by lazy loading
Parameters
Whether or not the command is being executed asynchronously
A timestamp indicating when the command started executing
Whether or not the command completed successfully, failed by throwing an exception, or, for async, was canceled
Some indication of the result value
The approximate amount of time it took to execute the command. Note that this is the time from sending the command to getting the
result object back. It does not include time to read the results.
Looking at the example output above, each of the four commands logged
are:
The query resulting from the call to context.Blogs.First
Notice that the ToString method of getting the SQL would not have worked for this query since “First” does not provide an
IQueryable on which ToString could be called
The query resulting from the lazy-loading of blog.Posts
Notice the parameter details for the key value for which lazy loading is happening
Only properties of the parameter that are set to non-default values are logged. For example, the Size property is only shown if it
is non-zero.
Two commands resulting from SaveChangesAsync; one for the update to change a post title, the other for an insert to add a new post
Notice the parameter details for the FK and Title properties
Notice that these commands are being executed asynchronously

Values for parameterised queries

I have a SQL statement String in Java which contains, among other things, the segment:
" AND \"Reference_No\" > ? "
I understand that this is a parameterized query, where the statement is precompiled and the parameters then added, in order to prevent injection attacks.
However, every example I've seen of this used, I have always seen accompanying code where the parameter values are then hard-coded in using some kind of setter method with code that runs something like:
setValue(1, "value1");
The program I am trying to understand does not appear to have this accompanying code, and I am trying to understand at what point a value is added to this SQL statement.
The application which uses this is a webUI servlet that sends and receives job transactions. More specifically, I am looking at the page that lists pending transactions.
I have a method which contains the following:
List<Job> query = getJdbcTemplate().query(sql.toString(),
new Object[]{minRef},
rowMapper);
sql contains the SQL statement segment in question.
Is the value-adding dealt with by the JdbcTemplate class? If so, how does it determine the values?

SQL injection in Symfony/Doctrine

Using parameters instead of placing values directly in the query string is done to prevent SQL injection attacks and should always be done:
... WHERE p.name > :name ...
->setParameter('name', 'edouardo')
Does this mean that if we use parameters like this, we will always be protected against SQL injections? While using a form (registration form of FOS), I put <b>eduardo</b> instead and this was persisted to the database with the tags. I don't really understand why using parameters is preventing against SQL injections...
Why are the tags persisted to the database like this? Is there a way to remove the tags by using Symfony's validation component?
Is there a general tip or method that we should be using before persisting data in the database in Symfony?
Start with reading on what's SQL injection.
SQL injection attack takes place when value put into the SQL alters the query. As a result the query performs something else that it was intended to perform.
Example would be using edouardo' OR '1'='1 as a value which would result in:
WHERE p.name > 'edouardo' OR '1'='1'
(so the condition is always true).
"<b>eduardo</b>" is a completely valid value. In some cases you will want to save it as submited (for example content management system). Of course it could break your HTML when you take it from the database and output directly. This should be solved by your templating engine (twig will automatically escape it).
If you want process data before passing it from a form to your entity use data transformers.
If you use parameters instead of concatenation when creating a request, the program is able to tell SQL keywords and values apart. It can therefore safely escape values that may contain malicious SQL code, so that this malicious does not get executed, but stored in a field, like it should.
HTML code injection is another problem, which has nothing to do with databases. This problem is solved when displaying the value, by using automatic output escaping, which will display <b>eduardo</b> instead of eduardo. This way, any malicious js / html code won't be interpreted : it will be displayed.

Does Rails recognize db view?

Is there a way that to access my db view as a table for a model?
Yes, you can use views just fine, they behave just like tables in ActiveRecord. I don't know what database you're using, but I use them in Oracle and haven't had a problem.
The only difference is that if you want to have your migrations automatically create them, you'll have to forego the typical create_table and instead execute SQL statements to create it.
With MongoDb, I accessed to the MongoDB Views with the following method.
Firstly you should create a dummy model to be able to use MongoDB connectors. You can manually create new file with the name view_names.rb and append below lines.
class ViewName
include Mongoid::Document
include Mongoid::Timestamps
end
And then to access records;
ViewName.collection.find({})
>> #<Mongo::Collection::View:0x0000000107cd4378>)
find gets MongoDB queries as parameter, so you can pass your logic as hash to find method.
{created_at: { '$lte': Date.todat - 2.week }}
View name on MongoDB should be plural view_names just as same with the others.