Error in SQL query when special characters used in password field - sql

I am using Visual Studio 2008 and Access 2013 as my database.
When I use special characters in a password field, my VB.Net code produces an SQL query error, especially when I am using a special char at the last chat.
For example, if I use jdjdj' as the password then an error occurs.
Normal passwords work. For example:
Admin123
123admin
123
admin
Where is the problem and how can I fix it?

You need to pass the password to the query as a parameter rather than concatenate it into the query string.
It doesn't just stop issues like this, it's also to stop malicious users deliberately taking advantage of your shortcut, to easily gain access to the database.
Check out How do I create a parameterized SQL query? Why Should I?

Related

How to receive SQL syntax error using SQL injection?

I'm doing some webpentesting exercises and there is this one task saying that I need to make a new account with this name and this password by using SQL injection. On the web page there is a text input username and another text input 'password'. I can enter whatever characters I want inside the username text-input but inside the password text input I need to type a specific injection.
I know I need to inject insert query but the thing is I don't know the table name. In order to insert a new user I need to know the table name so I'm wondering how can I make the web showing me an error with tablename revealed.
The error showing should be like:
Unexpected end of command in statement [SELECT * FROM (tablename) WHERE...]
I tried to enter with just one character (maybe >1 chars are required) inside the password field to make the error show or even delete the parameter text input password. But it just won't show the SQL syntax error.
So the question is: How can I make use of the exploit to make the web page view the SQL syntax error with table name revealed?
And why doesn't injection work on username field but it does on password field?
The first thing is understand the difference between "application" errors (for example, "the user doesn't exist") and execution errors, in which the application fails itself, like the "Unexpected end of command" you mention. The first case is not usually a problem from the security point of view (unless the application is very badly programmed), the second one is what could allow hacking.
A well programmed web application should ideally only have application errors, but the more realistic approach is cope with unexpected execution errors in way that don't make it vulnerable. Also, application should process any user input in a way that don't cause an execution error.
It seems that they are teaching you the most flagrant case that allows SQL injection, apps than don't do any processing to user input (so it's very easy put text in an input field that cause an execution error), and that don't cope with execution errors (in this case, showing the internal execution message to the user).
A common mistake in web applications is constructing the SQL query with string concatenation, so the simplest way of make it fail is using the string delimiter (') in a field, causing the string value to end prematurely. In an sloppy web app it would cause an execution error that shows the full error message, usually including the table name.
From there you craft a SQL query in the input field that insert the user in the table, you could find examples online (note that you need at least basic knowledge on SQL and PHP (or ASP, Java, etc.), in order to do SQL injection, since you need to know how the database access works in order to make it fail).
Finally, SQL injection could work in any input field that is not properly processed, but it depends on how the application is programmed. I suppose that both fields would work but it will be easy do that with the password field because probably is the last one in the SQL query.

SQL statement against Access 2010 DB not working with ODBC

I'm attempting to run a simple statement against an Access DB to find records.
Data validation in the records was horrible, and I cannot sanitize it. Meaning, it must be preserved as is.
I need to be able to search against a string with white space and hyphen characters removed. The following statement will work in Access 2010 direct:
select * from dummy where Replace(Replace([data1],' ',''),'-','') = 'ABCD1234';
Running it from an ODBC connection via PHP will not. It produces the following error:
SQL error: [Microsoft][ODBC Microsoft Access Driver] Undefined function 'Replace' in expression., SQL state 37000 in SQLExecDirect
Creating a query in the database that runs the function and attempting to search its values indirectly causes the same error:
select * from dummy_indirect where Expr1 = 'ABCD1234';
I've attempted to use both ODBC drivers present. ODBCJR32.dll (03/22/2010) and ACEODBC.dll (02/18/2007). To my knowledge these should be current as it was installed with the full Access 2010 and Access 2010 Database Engine.
Any ideas on how to work around this error and achieve the same effect are welcome. Please note, that I cannot alter the database in way, shape, or form. That indirect query was created in another mdb file that has the original tables linked from the original DB.
* Update *
OleDB did not really affect anything.
$dsn= "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\dummy.mdb;";
I'm not attempting to use it as a web backend either. I'm not a sadomasochist.
There is a legacy system that I must support that does use Access as a backend. Data gets populated there from other old systems that I must integrate into more modern systems. Hence, the creation of an API with Apache/PHP that is running on the server supporting the legacy system.
I need to be able to search a table that has an alphanumeric case identifier to get a numeric identifier that is unique and tied to a generator (Autonumber in access). Users have been using it a trash box for years (inconsistent data entry with sporadic notations) so the only solution I have is to strip everything except alphanumeric out of both the field value and the search value and attempt to perform a LIKE comparison against it.
If not replace() which is access supported, what ODBC compatible functions exist that I can use do the same kind of comparison?
Just to recap, the Access db engine will not recognize the Replace() function unless your query is run from within an Access application session. Any attempt from outside Access will trigger that "Undefined function" error message. You can't avoid the error by switching from ODBC to OleDb as the connection method. And you also can't trick the engine into using Replace() by hiding it in separate query (in the same or another Access db) and using that query as the data source for your main query.
This behavior is determined by Access' sandbox mode. That linked page includes a list of functions which are available in the default sandbox mode. That page also describes how you can alter the sandbox mode. If you absolutely must have Replace() available for your query, perhaps the lowest setting (0) would allow it. However, I'm not recommending you do that. I've never done it myself, so don't know anything about the consequences.
As for alternatives for Replace(), it would help to know about the variability in the values you're searching. If the space or dash characters appear in only one or a few consistent positions, you could do a pattern match with a Like expression. For example, if the search field values consist of 4 letters, an optional space or dash, followed by 4 digits, a WHERE clause like this should work for the variations of "ABCD1234":
SELECT * FROM dummy
WHERE
data1 = 'ABCD1234'
OR data1 Like 'ABCD[- ]1234';
Another possibility is to compare against a list of values:
SELECT * FROM dummy
WHERE
data1 IN ('ABCD1234','ABCD 1234','ABCD-1234');
However if your search field values can include any number of spaces or dashes at any position within the string, that approach is no good. And I would look real hard for some way to make the query task easier:
You can't clean the stored values because you're prohibited from altering the original Access db in any way. Perhaps you could create a new Access db, import the data, and clean that instead.
Set up the original Access db as a linked server in SQL Server and build your query to take advantage of SQL Server features.
Surrender. :-( Pull in a larger data set to your PHP client code, and evaluate which rows to use vs. which to ignore.
I'm not sure you can do this with ODBC and your constraints. The MS Access driver is limited (by design; MS wants you to use SQL Server for back ends).
Can you use OLEDB? that might be an option.

query string sql injection

Examining some logs in my web site, I discovered that a bunch of querystring variables contains sql injection snippets:
'myvalue AND CHAR(124) USER CHAR(124)=0 AND ='
'myvalue AND 1=2'
How do you sanitize the querystring variables?
The platform is ASP.NET, fm 4.0, SQL Server 2008. So go with the parametrized query. But there is a part of the application (an old one) running classic ASP. There is no parametrized query in classic ASP...
You shouldn't worry about sanitizing query string values.
You should worry about writing code that doesn't have SQL Injection vectors to begin with. Parameterized Queries are the way to go. Depending on your platform, the exact SQL can vary a bit.
As it seems you already know how to work with parameterized queries in .NET, I'll skip that.
As for the Classic ASP page, you should take a look at How To Call a Parameterized Query with ADO (paying special attention to the change at the bottom to use a SQL Statement rather than a Stored Procedure).
I think I had two websites of mine hacked by such a hack! The way to stop the hack is to check the data being read before it hits the database.
If the value is a number check the string has only chars 0-9 in it, if not send them to the page not found!
If you are using strings like 'yes', 'no', 'true', 'false', values that you define don't add them to the database string directly, check for them with an if such as,
If(request("dog").equals("true")){...
finally if the value is a string that the client has entered then watch for ' char. An insertion hack works by first closing the string with ' then the expression with ; and then adding and update, insert or delete statement. so if ' ; and for good luck " is escaped the string cannot be closed.
Note: the same thing is true for text boxes, form sends and Ajax.
Always do these checks on the server as a hacker can always fake a page.

Windows Login Names and their impact on SQL Server 2005

Does anyone know of the impact on SQL Server of adopting 'two part' user Windows Loginnames in the form "fred.bloggs" instead of "bloggsf"?
I have scoured the Microsoft Knowledgebase and can nothing clear about one or the other: only that all examples shown by them are in the 'single word' format.
I have tried to use fred.bloggs ( that is fred dot bloggs ) in some SQL statements and get error messages, so they obviously cannot be used in a straight forward form.
You need to wrap a login like this in brackets, like: [your.login]
There is no impact on the SQL Server engine and performance.
A user name is a user name, whether there is a . in the middle or not.
The only issue is that of how the name is interpreted - ensure you use [] when specifying a user name, otherwise SQL will interpret the part before the . as a schema name.
So, for CREATE LOGIN, you should do:
CREATE LOGIN [xxxxx.yyyyy]

How to prevent 'DROP BOBBY TABLES' when user enters a password with special characters?

In our ancient Classic ASP environment, we utilize OWASP to get the password from the request object and encrypt non-alphanumeric characters. This is a first line of defense to preventing sql injection. We use other methods for full sql injection prevention.
The problem is, when we are collecting data to put together an HTTP post message and just grab the password from the user input, OWASP it and send it along. The password is therefore incorrect.
Example: Password freddie$cougar becomes freddie&36;cougar
What we ended up doing was assuming that a 50 character text field was not enough space to do much sql injection and changed the code so we didn't OWASP the password coming in. This feels a bit scary.
Is their a better way?
The code is written in vbScript.
A better solution is to convert all queries to parameterized ones.
Here is a 12 year old article explaining how :)
Why are you sending the password in clear text? Calculate a hash value for the password and send that one. This would allow you to prevent SQL injection and to avoid man-in-the-middle type attacks.
In any case, you have to also clean up the data as it comes to your server. Even if your vbscripts does client-side validation, it would be trivial to attack your service by bypassing your script and hand-crafting a packet with malicious input in it.
Consider moving your SQL statements to stored procedures, and ensure that you don't use dynamic SQL within those stored procs.
Dim userPwd = Trim(Request.QueryString("userPwd"))
'--- Create and append parameter for Password
Set pwdParameter = cmd.CreateParameter("#UserPassword", ad_nVarChar, adParamInput, 50, userPwd)
cmd.Parameters.Append pwdParameter
Aside, it's definitely best to not even store the pwd in your database, but rather a salted hash.
The method above is preferred, no matter what string you're sending to your database, as it'll avoid executing directly as an adhoc statement, and will avoid SQL injection, as long as you're not using the parameter with dynamic SQL within the stored proc.
A lot of sites limit the set of characters that can be used in passwords - choose a set that is not going to cause you grief. That probably means alphanumerics, and some punctuation (comma, full stop, dash). Having suggested that, those sites annoy me - I use a rich set of characters in my passwords when given the chance to do so, and on the alphanumeric-only sites I usually end up using nonsense like 'IHateNoPunctSites' as the password.
What about shipping the password as a hex-encoded string, or a base-64 encoded string? You can then decode the string at the end, being as careful as necessary to prevent any injection without limiting the character set that is used in the password. When you need to check the password, you can ensure you are doing it cleanly using a parameterized query. Or you can hash the password with its salt before sending the query off to the password file. You should not be doing much with passwords anyway.