SQL, Microsoft SQl - sql

I was trying to stress test my system's login unit. My system is designed like this -
if the user enters userid - abcd and password pass then the server takes these parameters and prepares an sql command and fires it to the microsoft database-
select password from UserInformationTable where userid = 'abcd';
The returned value is compared with the given password pass and result is then sent to the client.
I successfully broken into the system using the following method -
user enters userid - <abcd1 or drop table UserInformationTable >. This worked and my complete UserInformationTable got dropped.
Is there any graceful way of handling such a hacking problem. One way is to detect 'or' substring in the userid, but I did not find this very graceful. Is there any way I can restrict the no. of queries in a statement in microsoft sql ?
Thanks and Regards,
Radz

This is the SQL injection problem illustrated by the famous "Bobby Tables" cartoon.
Here is some info on how to fix it for MS SQL. Read especially #Rook's answer.

You have two problems.
You are subject to SQL injection attack as described by other users. Solve that problem by sanitizing your input and/or using parameterized queries.
You should neither store nor transmit plain text passwords. Why? See this story on Slashdot. The solution to this problem is to use one-way encryption to create a password hash to store in the database. When the user tries to log in use the same encryption on the password he or she provides, then search your database to see if a row exists with the same userid and password hash.

Use parameters in SQL queries. They automatically prevent this. Something like this in C#:
SqlCommand comm = new SqlCommand(conn);
comm.CommandText = "SELECT * FROM foo WHERE bar = #id";
comm.CommandType = CommandType.Text;
SqlParameter param = new SqlParameter("#id", DbType.Int64);
param.Value = 3; // The actual value that replaces #id
comm.Parameters.Add(param);
// ...
This not only applies to C#, but basically all modern DB systems and languages support parameterized queries <- google it.
And second, your first query can be changed to:
SELECT userid FROM users WHERE username = 'foo' AND password = 'bar'
Then just count how many rows you got returned, if it's 0, then the user entered the wrong password.

Related

What programming language is this code from?

I am looking at some SQL code:
txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;
I know in php it uses $_GET or $_POST to retrieve the values entered in a form so I am just wondering what is the language the first statement is written in that is retrieving the values?
I'm going to answer this definitively. No, not the language question, but the actual, important part of that code snippet.
Do Not Open Yourself To SQL Injection Attacks.
That code puts in the text contents of UserId directly into the SQL statement. Which means that someone can enter something like:
UserId=-1 or (1=1)
... and get the entire table. Or:
UserId=-1; NewSQLStatementStartsHere
... and start running malicious SQL statements on your server.
Never inject raw values into SQL. Always use parameterized values. SQL Injection Attack is still the #1 cause of security vulnerabilities in software.

Why do Parameterized queries allow for moving user data out of string to be interpreted?

From https://en.wikipedia.org/wiki/Code_injection#Preventing_problems
To prevent code injection problems, utilize secure input and output handling, such as:
Using APIs that, if used properly, are secure against all input characters. Parameterized queries (also known as "Compiled queries", "prepared statements", "bound variables") allows for moving user data out of string to be interpreted. Additionally Criteria API[7] and similar APIs move away from the concept of command strings to be created and interpreted.
I was wondering how and why "parameterized queries (also known as "Compiled queries", "prepared statements", "bound variables") allows for moving user data out of string to be interpreted" and prevent or mitigate code injection problems?
Can you also provide some examples in explanation?
Thanks.
Compiled queries use special syntax that the database understands. They usually add placeholders for parameters such as in:
select * from applicant where name = ?
select * from applicant where name = :name
The exact syntax depends on the specific technology: JDBC, ODBC, etc.
Now, once those queries are sent to the database (without the specific parameter values), the database "saves" them. Later on (usually in the same database session), you can run them many times, by just providing the parameter values each time.
SQL Injection Safety
They are also safe against SQL injection. For example, if in the previous query instead of a simple value such as Mary you used the value x'; delete from applicant; -- the database will work safely. It would run something like:
select * from applicant where name = 'x; delete from applicant; --'
This query won't probably find anything and will be safe.
If instead you didn't use compiled query, but just decided to concatenate the SQL as a string you would do something like:
String sql = "select * from applicant where name = '" + param1 + "'";
And would end up with the UNSAFE query:
select * from applicant where name = 'x'; delete from applicant; --
This one would run two queries. The second one will delete all the information from your table. Probably not what you want.

Create Query SQL Injection free while getting all the content of table

I am getting all the content from the table using following queries
SqlCmd.CommandText = "Select * from Product";
SqlCmd.connection = myConnection();
myConnection.open();
reader = sqlCmd.ExecuteReader();
As far I know when we use input parameters in select then there is possible attack of SQL injection. So how do we secure when we are not using where clause.
Can we prevent SQL injection using following query.
SqlCmd.CommandText = "Select Name from Product";
Injection occurs when placing variables in a query that user's can put code into. Users overwrite your statements and use their own (injection of SQL code). Your select query does not meet that criteria since users cant interact with it.
There should be some functions in ASP.net that allow you to premake statements. I don't use asp.net but a google search should help you know that your in the right direction.

Redis store design for traditional "select * from where and " type query

I'm new to Redis, I am now learning it by trying to make a login function.
Suppose I have a table named User (id, username, password) in traditional SQL database, what's the proper way to design the Redis store for a table, so that I may achieve some sql-style-query like "select * from user where username=xxx and password=yyy"?
Is it a good way to set the key: username+password and the value: username "root" password "admin" using Hash?
Redis is not a replacement for SQL databases. They have different purposes.
In Redis you should design based on how you will access the data.
See this SO question.
Also this tutorial by Simon Willison is very interesting even though it has some years.
I suspect your query doesn't actually need to be select * from user where username=xxx and password=yyy, but instead just looking up by username and then verifying the password is correct.
Using Redis you can store the user information by the username (this is your primary/unique key) and then in your code verify the password is correct. As #tadman has stated in the comments - please don't store passwords as plain text, that's a huge security hole right there

Best way to store Sql Scripts in a database table

I need to store stored procedure execution scripts in a database table.
As an example:
exec proc_name 'somedata'
These are for execution at a later time after the data that will be changed has gone through a moderation process.
What is the best way to cleanse the script so that the statement cannot be used for sql injection.
Is there a specific type for encoding that I can use? Or is it as simple as doing a replacement on the '
Then it sounds like you would want to use a varchar(max) column and have a separate table for parameters.. If you use Parameters you should be safe from SQL injections. See quickie C# example below:
C# psuedo-code example
SQLCommand command = new SQLCommand("select * from myScripts where scriptid = #scriptid");
SQLParameter param = new SQLParameter("#scriptid", 12, int);
...new SQLCommand("select * from myParams where scriptid = #scriptid");
...new SQLParameter...
DataReader dr = new blah blah...
SQLCommand userCommand = new SQLCommand(dr['sql']);
foreach (parameter in params)
{
userCommand.Parameter.Add(parameter['name'], value);
}
userCommand.Execute...
There is no way to "cleanse" scripts.
The only way to secure your code is to separate the code from data. And "cleanse" the data only.
That's why we have our code separated from data.
The code is solid and secured, and data is variable and haver to be "cleansed".
As you are breaking this fundamental law, treating the code as data, there is no way to secure it.
Judging by the utter unusualness of the task, I'd say there is a proper solution for sure.
You just choose the wrong architecture.
So, you'd better ask another question, something like "I want to deal with quite complex metadata structure (with the structure and the purpose provided)" and you will get a proper solution that will require no storing SQL codes among the data.
You can either store your scripts for later execution in a Stored Procedure or a scheduled job. I don't see any reason for encoding a stored procedure, as you can put user privileges to prevent different users from reading or even seeing them.