SQL injection on autoincrement - mysql

I have been looking up SQL injection lately and what they are, what they do and how to stop them. Most place talk about username stored by users in select stamens causing problems such as 'OR 1 but if I was to only use a auto incremented id to select information from a database and not a user input value would this also prevent sql injections?

SQL Injection applies specifically to the shape of the query - it says nothing about queries that can accidentally leak information from other means.
SQL injection is a code injection technique, used to attack data driven applications, in which malicious SQL statements [or expressions] are inserted into an entry field for execution..
Using placeholders eliminates SQL Injection1,
but..
..just because a system is free from SQL Injection does not mean that it is safe from other vulnerabilities.
For instance, imagine this query, where #OWNER represents a placeholder.
select *
from emails
where owner = #OWNER
This query is free from SQL injection, but if an attacker can specify an arbitrary "OWNER" value, then they can access someone else's email - oops! This is just a security vulnerability; not SQL Injection.
1 Use placeholders for all data that comes from variables.
It doesn't matter if it is from the user or not. It doesn't matter if the value is guaranteed to be an integer (even one from an auto-increment column) or not. Just use placeholders consistently - then you'll have cleaner queries and more time to focus on other problems.

Everyone who is looking up on SQL injection, have to understand that there is no way to exploit a non-existent injection. On the other hand, once injection is possible, there is potentially infinite number of possible exploits.
Means one should never care of particular exploits. But always concentrate on making injection impossible.

Related

SQL FullText Indexes and SQL Injection

Is there any known danger with exposing the use of a FullText index to internal and possibly public users?
Assuming the queries are properly parameterized, is there any way that a user could abuse the inputs to trigger a SQL injection or denial of service attack?
// SQL Server
select * from content_table WHERE CONTAINS((Title, Subtitle, Body), #fullTextSearch);
// MySQL
select * from content_table WHERE MATCH(Title, Subtitle, Body) AGAINST (#fullTextSearch);
// Oracle
select * from content_table WHERE CONTAINS(Body, #fullTextSearch);
The trigger for this question is the large variety of inputs a user could specify and the fact that the different SQL servers have different query syntax and at least some (MySQL) will return a syntax error if an invalid query is specified.
'FORMSOF(INFLECTIONAL, model NEAR airplane)'
'NEAR((term1, term2),5) AND term3'
'NEAR((term1, term2),5) OR NEAR((term3, term4),2, TRUE)'
'+join +(>left <right)'
'electric INPATH (/purchaseOrder/items/item/comment)'
When talking about SQL injection the risk is that someone can introduce SQL keywords into the query itself by adding SQL to a data parameter.
This is why separation of data and query is absolutely critical. This normally plays out by using placeholder values, as in:
SELECT * FROM content_table WHERE MATCH(Title, Subtitle, Body) AGAINST (?);
In the case of search there's often two levels you need to be aware of:
The SQL layer where you're using raw SQL keywords to express the query conditions, such as WHERE x=? AND y=?
The search layer where you're expressing conditions within a string, like WHERE CONTAINS(?) which has a bound data parameter '"computer software" NEAR hardware)'
Note that the second form has a syntax within a string, so if you're exposing that you're not at risk of SQL injection per-se, but you may end up receiving a lot of syntax errors caused by bad user input that you need to handle.
In the first case if you need to compose the query conditions you need to follow the usual rules:
Do not permit:
Inclusion of unknown fields into the query.
Inclusion of unknown operators into the query.
Maintain as strict a separation between query and data as is practical.
You may need to parse the request's data into components that can be recomposed into a SQL query. This can get messy, especially if you're allowing a lot of latitude in how things can be searched, so try and keep it as simple and testable as possible.
If you have unit tests, include one that's deliberately hostile and tries to introduce invalid or injection-type data into the query. Ensure the data is properly contained.
Note: If you're calling a stored procedure using placeholder values, but the stored procedure composes SQL statements using concatenation you're still at risk, so you need to be absolutely certain you're keeping the data separated from the query. If you have a query with zero user data introduced in it there is no risk of SQL injection.

are stored procedures really secure against sql injections

I need to convince someone that he needs to sanitize the user input in addition to the user of stored procedures. well I know I sound crazy but I do not feel comfortable enough with store procedures only. My first reason is that I am able to cause errors in the stored procedure but because of the fact that the application itself handles errors such that error messages are coded it is difficult for outside to understand the what there are. but I still think that this is not secure.
Does any one has a suggestion ? or am I wrong to doubt stored procedures?
No it's not safe on it's own. You can also do in a stored procedure something like this:
SET #sql = 'Select * from products where name like ''' +#spinput+''' ';
exec(#sql);
With the wrong value in #spinput you can inject code.
However you can write stored procedures that are safe against sql injection.
Even if you use proper parameters, you can still mess with the database. You could insert a script that goes in as a parameter, but when it's displayed on a web page starts doing something it shouldn't. Use parameters to ensure your database is used as intended, but also sanitize the output later - never trust user-entered data.
Using stored procedures normally protects against SQL injection, but is not the only solution to prevent SQL injections, and it doesn't protect against all forms of SQL injection.
It's not the stored procedure itself that makes the big difference, but parameterised queries, which is the most common way to call a stored procedure. By putting the values used by the query in parameters, you let the database library handle them instead of having to escape them correctly yourself.
It's possible to write code that is safe against SQL injections without using parameterised queries, but it's difficult. You have to know exactly what characters you need to escape in a string for the specific database that you are using, and if you get it wrong you are pretty much as unprotected as if you didn't know about SQL injections at all.
If you use parameterised queries, then the step of sending the values into the database is safe from SQL injection, but the query itself might not be. If the query generates and executes SQL code itself, you have the same problem with escaping strings correctly. It's however not so usual to create SQL code in the SQL code, and if you do it you are very aware of that you are doing it.

mySQL: Stored procedures are more secure than queries?

I have a website using mySQL database and I want to do common tasks like add users, modify their info, etc. I can do it perfectly with regular queries. Im using prepared statements to increment security.
Should I use stored procedures to increment the security or the results will be the same? I though that may be using stored procedures I can restrict the direct interaction that a possible attacker could have with the real query. I'm wrong?
I guess it would depend on what language youre using. Using a prepared statement with a sql string that contains all of the sql to be executed, or using a prepared statement with a sql string that executes a stored procedure are going to be about equivalent in most languages. The language should take care of the security around the prepared statement. C# for example will validate the input, so sql injection vulnerabilities are greatly reduced unless your prepared statement is written so poorly that feeding it bad (but expected, ie, 1 vs 0) variables will dramatically change the result set. Other languages may not provide the same level of validation though, so there may be an advantage depending on exactly what your stored proc looks like.
Using a stored procedure is better for maintainability, but there are not many scenarios where its going to provide any sort of change in security level, assuming the program is properly designed to begin with. The only example i can think of off the top of my head would be a stored procedure that takes raw sql strings from user input, and then executes that sql against the db. This is actually less secure than using a prepared statement unless you went to great lengths to validate the acceptable input, in which case you better have a really good reason for using such a stored proc in the first place.
Basically, what I'm saying boils down to the fact that you're going to need to read the documentation for your language about prepared statements, and determine what vulnerabilities, if any, using prepared statements may have, and whether or not those can be eliminated in your specific scenario by switching to a prepared statement that calls out a stored procedure instead of executing a sql query directly.
The results would be the same (assuming that you set your stored procedure up right).
there appears to be a pretty good write up on it here. Though I would never suggest you try to escape user input yourself. (They mention this as option 3)

Mysql Database Attacks other than Sql Injection

I am using mysqli prepared statements and bound variables.
Then to prevent sql injection, am I need to do anything else(eg: data type validation, filtering, sanitize, string escape etc ) with user input ?
Is there any other way of attacking MySql database other than Sql Injection ?
To prevent SQL injection you have to format your query properly.
Every literal that have to be added to the query dynamically, have to be properly formatted.
Not only data literals like strings and numbers but all of them, including operators and identifiers.
The only proper way to make values formatted is prepared statements.
For the identifiers and operators you will need also filtering, to let only allowed ones into query.
Whatever user input should not be involved at all. It's destination, not source that matters.
Is there any other way of attacking MySql database other than Sql Injection ?
sure thing. But the topic is too broad to make you secured by means of a forum post. Better hire a DBA.

Have I found an SQL injection bug in SQL server?

So I was playing with my MS SQL Server 2008 app to see how good it is protected against SQL injections. The app lets users to create views in the database.
Now consider the following:
create view dbo.[]]; drop database foo--] as select 1 as [hi!]
This creates a view with a name of ]; drop database foo--. It is valid and you can select from it (returns the number 1, obviously).
Strange thing #1:
In SQL Management Studio, the query SELECT [hi!] FROM [dbo].[]]; drop database foo--] is red-underlined as incorrect, claiming that the object name is not valid. Nevertheless, it executes and returns the 1.
Strange thing #2:
Call to OBJECT_ID(']; drop database foo--') yields NULL (which means the object does not exist), but the following query returns information about the view properly:
select * from sys.objects where name = ']; drop database foo--';
Are those bugs or am I missing a point?
You're missing the point. SQL Server can't protect itself against SQL injection - if somebody has direct access to your database then you've already been pwned. It's your application that needs to protect against SQL injection by parameterizing queries, and preventing these kinds of statements from ever making it to the database.
1: that only means the intellisense parser is not up to par witht the finer details of SQL syntax. While it may be an intellisense bug, it is not an injection vector.
2: object_id() accepts multipart names, so it needs the name in quotes if ambiguous: select object_id('[]]; drop database foo--]')
That's like using your key to get into your car and then saying "hey there's a security hole, I'm allowed to steal the radio"
It seems the problem is that you are yourself causing SQL injection by accepting user input and using it as SQL statement text.
The fact that you "properly escaped" the ] (by substituting with ]]) really doesn't matter - it's you allowing the user input to be used as anything else but a value by definition means you allow SQL injection.