Best Way to Prevent SQL Injection Using Javascript or C#? - c#

I'm currently writing an application which uses ajax on the front end and ASP.NET (C#) on the back end..
A Small Part of the application does an AJAX call to the backend code (to get entries from the SQL database)
How can i prevent SQL of JScript injection?
I know it is generally unsecure to validate with javascript because javascript can be turned off but as this is an AJAX call so if the user has javascript turned off the AJAX will never run.
Whats the best way of validating or escaping the input?
Like Add_Slashes() in PHP?
Thanks
Daniel

Protection against SQL injection needs to take place on server side, regardless where the incoming call comes from.
Javascript-based sanitation methods are always useless because Javascript runs on client side, and therefore can be forged.
This also applies for AJAX calls: The client doesn't need to turn JavaScript off; they just need to manipulate the Javascript code they download from your site to fake validation.
Never, ever, ever rely on client side data sanitation.

Use parametrized queries, never build SQL code strings.

I think use Parametirized Query instead of Adhoc SQL

Whatever you do, you ALWAYS have to run validation code on the server.
The ajax call inevitably hits the server, so validate user input there for avoiding sql injection attacks.
The only reason for validating user input on the client is to avoid a call to the server, eg, a user didn't fill in a required field.
On the server, if you use LINQ to SQL or Entities to update the database, you get free parametrized queries which avoid SQL Injection attacks.
Never, EVER write plain strings of sql and pass that to the database, unless you EXPLICITLY use parametrized queries.
But just use LINQ and you will keep yourself (and your client!) safe.

Using Bind Parameters is the way to prevent SQL injection:
http://use-the-index-luke.com/where-clause/bind-parameters
It is ok to perform client side validation as well, but just to improve usability.

The lack of security of Javascript validation has got nothing to do with the fact that Javascript might be turned off.
That Javascript might be turned off means that an honest mistake may do something wrong, or result in a default server message rather than a helpful one. While they could accidentally trigger a security issue (I have actually done this as a user, the worse bit is my input was valid, but one of the people whose names I was entering had a ' in it, more on that below). This affects honest but imperfect users, not crackers.
A cracker should be able to replay an AJAX request with different values in around 30seconds, including time spent making stupid threats on social media sites in another window. It's not technically difficult. That's why Javascript validation has no security value, and is solely to make the validation for honest mistakes more user-friendly (by having a more immediate response, and being able to direct focus to the incorrect field).
Further, this is generally not a matter of validation, but of encoding. Some people try to "fix" SQL injection attacks by banning the sequences that can cause them, which most often means banning apostrophe characters. Then they put this logic onto fields that might reasonably contain apostrophes. In particular, never do this with name fields; people really don't like being told that their name is "wrong" and at worse it can feel like racism or cultural insensitivity, since you will find them a lot in e.g. French or Irish names but not so often in English or German names (yes I know English names of Norman origin often having them, but I have also heard people with apostrophes in their names ranting about the stupid racist website that won't let them input their name correctly, which is probably the worse time to bring up the Normans as a correction).
Validate for the obviously wrong in Javascript as a means to improve UI.
Validate for the obviously wrong on the server as both a means to improve UI and a means to catch attacks.
Pass your data to other layers in the correct manner. In terms of SQL this would mean encoding string delimiters (again, ' is the most common case, but some other delimiters are possible with some databases), for which the best means of doing so is through a library that does so for you. In the case of C# this would mean using Parameters with ADO.NET rather than building SQL yourself (there are other advantages to this too).

There are two concepts that are often mixed here. Validation and encoding/escaping. Adding a slash is an attempt to encode data for a context. Validation is about making sure the data is valid according to the domain.
To answer your question, the best way to avoid these problem is twofold. First validate the data on server-side (make sure a number is indeed a number etc.). However validation is not enough to avoid these problems. The name "O'Brian" is an example of a valid name, so it would pass validation, but it may cause problems in javascript or in a SQL-statement.
So the next part is context-aware encoding. When sticking the data in a SQL statement, you need to escape/encode for SQL. The easiest and safest way to do this, is to use parameterized queries, where everything is handled for you.
More info: http://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
When the data is sent back to the client, you need to escape/encode the data for the format you are returning the data in. To avoid script injection you need to know if you are escaping inside a json-string, inside an HTML-attribute etc. etc.. See here for information about how to escape for the different contexts: http://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
Use AntiXSS for escaping/encoding for web: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=f4cd231b-7e06-445b-bec7-343e5884e651

Related

Simple Linq Security

I'm trying to find the security flaws within my ASP.NET login page. How would I go about sanitizing the user input so that XSS and SQL injection is not possible? I feel that my Linq queries are secure but I could be wrong. Please let me know if you need any more information.
String username = usernameTxt.Text.toString();
Company check = (from u in context.Company
where u.companyadminUserName.Equals(username)
select u).FirstOrDefault();
if (check == null)
{
return BAD_USER;
}
else
{
return GOOD_USER;
}
Well, this is where it helps to know something about the implementation of LINQ-to-SQL you are using. I would imagine that every implementation would by default escape arguments to the LINQ extension methods, but never hurts to double-check.
In general, you want there to always be a middle-man sitting between the user interface and the service layer. You probably have them all over your apps; validators. They are more obviously-necessary in the case of validating that a number is a number or that a zip code is a zip code, but nowhere are the stakes higher than for validating that all user input is not unescaped. But that's not good enough - that's just the beginning.
What I would recommend is to institute something like what ASP.NET provides at the boundary - to prevent HTML from being inputted into user interface inputs as well - but also at the boundary between your thin controller and thick service, or as its own layer.
In such a design, maybe you can implement an attribute or annotation like InterrogateTheCarrierAttribute on every database input parameter (assuming you have parameterized into functions all of your database calls, and you are not concatenating strings to make queries). And on anything like it: every Powershell call wrapper or sh wrapper or function to access bank accounts and withdraw money, etc. Then, as the objects make their way in one form or another, every time they cross a "validation boundary," they have to be sanitized as if there is no guarantee of sanitation beyond. This is overkill but unless the validation is costly, why not?
Think of this: instead of bad user interface input, what if a text file or a trusted web service becomes compromised instead? If you think about it in terms of "this tier, this tier," you can convince yourself that there is safety where there is not. Microsoft's web server would never send you malformed packets, right? Your logger would never send your database bad SQL, right? But it can happen. So with the "cross-cutting" approach to validation, you always validate at the boundaries, at least on the way in, and possibly on the way out. And by doing so, you make it less likely for a bad assumption to leave your database interface wide open.
Example: take your query. The issue at stake is 1) whether username gets escaped, and 2) whether it is possible for an unescaped username to somehow overcome the fact that LINQ to SQL is a major abstraction and doesn't lend itself immediately to injection.
Now you should know the answers to those, but our system shouldn't require omniscience to be effective. So, I propose implementing a cross-cutting layer for validation, however you want to do it.

How do I prevent malicious SQL injection attacks while allowing benign SQL injection?

I'm writing an ASP.NET MVC4 application which ultimately builds a SQL SELECT statement dynamically to be stored and executed at a later time. The structure of the dynamic SQL is determined by user configuration in a user-friendly manner, with standard checkboxes, dropdowns, and freeform-entry textboxes. It would be simple enough to validate the input and build the SQL string using parameterized queries, except that I need to allow advanced users the ability to enter custom SQL to be injected directly into the SELECT and WHERE clauses. So what techniques can I use to cleanse the custom SQL expressions or otherwise guard against unwanted input from a clever user? I can easily enough parse the string for suspect keywords and blacklist insert/update/delete/etc., but something tells me that's not going to protect me 100%.
I'm happy to provide more details about exactly what I'm doing here, but I'm not sure what other details would be helpful, since I feel like my problem, while probably not common, is pretty generic.
Contrary to other views, it is possible to do this safely (just look at Data Explorer). Here are the four things you can do to make it happen:
Account Security
Sql Server will let you restrict permissions available to the account used to make the connection to the database. Only grant read permissions, and only to the appropriate tables. Then someone could inject malicious code 'til they're blue in the face, but it will fail at the compile step because they don't have enough permissions. That may mean using a different connection string for this access than for other parts of the application.
Note that this is good for sql code, but there are other kinds of injection as well. If you ever show the query on the page (in full or part) back to the user before running it, you should also look out for javascript injection attacks such as cross site scripting.
Query Governor
You also want to defend against denial of service attacks. Sql databases make it easy for these to happen even by accident, simply from constructing an inefficient query. To combat this threat, you should take a look at the query governor feature in Sql Server. Note that tuning this thing is tricky.
Quarantine
The safest course is to also use a dedicated, sanitized reporting database, hosted on a dedicated server. This ensures that no query can impact production, either in terms of performance or a breached server or account. There are features in sql server such as SSIS that you can use to automate populating your reporting DB from production.
Use a Product
One of the things about security is that you never want to find yourself building your own secured system. It's easy to create something that seems to work, passes tests, but is flawed in subtle ways that lead to breaches later. You want to rely on a product from a vendor that does this kind of thing as a core competency. This means it's battle tested (inevitable bugs are found and fixed) and if there is a flaw, that flaw might end up exposed for someone else first. It also means the vendor can provide support and a level of indemnification. Normally I talk about this in terms of authentication systems, but this rule can apply to sql injection defense as well.
In this case, it might be worth checking out Stack Overflow's Data Explorer. This is a tool to allow the construction of arbitrary queries by untrusted users. The project is open source, so you can see for yourself what they've done to ensure safety, or even just fork that project for your own use. It's worth mentioning again that a big part of this tool's safety is that it is intended for use on a dedicated, sanitized database, so it does not exempt you from the other items.
When all is said and done, though, I think the comment to set up some views and provide access via reporting services is probably your best bet.
I think you can only achieve what you need by not providing a direct way to specify SQL.
That doesn't have to be a problem however. Basically you only need a subset of SQL for defining expressions (computed solumns in the SELECT) and predicates (for filtering in the WHERE). This can be handled with a self-made parser which has just enough power to do everything needed, but then "compiles" the expressions into real SQL code, without actually injecting anything directly.
This then validates the syntax and makes sure that no constructs can be fabricated which would allow for any injection. Also, it allows you to properly let the code generator parametrize the queries you generate as needed (for instance, all literals could be passed in as query parameters by your code generator).
I would never ever let users to run custom SQL statements against production server.
Which bad guys directly can attempt to read/write/modify on tables which they are not supposed to or other bad guys can compromise weak accounts and run SQL statements against to your server.
If you have pre-built system which creates sql statement according to html inputs then you can generate script on the back-end which will not hurt your database. Otherwise if users want something very custom, then let them upload their script, review it with your SQL Administrator and make sure it is "safe to execute" and run it to be scheduled.
If script is denied then let user know about it, and explain why their custom script is denied.
Use stored procedures, so any thing that comes from any user will be inserted as a parameter and never be executed.

When to worry about SQL injection protection

Small background: I'm the only programmer for this company. I'm working with pre-existing frameworks.
That said, the company has a dll(Database.dll) which contains "all the database interactions I need". As in, it has a Query(), Update(), Insert(), etc. Now, the project I'm writing sets a reference to Database.dll. My project accepts zero user input. The closest thing to user input is a dropdown box that the user can select a date from. Not having much experience with it, I'm curious if I still need to worry about SQL injections? And if so, would a query written like
var query = string.Format("SELECT timestamp FROM table1 WHERE date = \"{0}\"
AND measured_dist = bit_loc AND rop > 0" , Date))
be sufficient as a parameterized query? Keep in mind, all of the query execution is handled by the pre-existing Query() that I'm told I have to use, and can't edit.
EDIT
This program is a WinForm application.
As noted in comments, the answer is "always". Since it would be so easy to add a parameter to that and do it properly, rather than concatenation: just do it right first time. Also: have you considered that injection is not the only problem in the code you've shown? That code is also susceptible to localisation / internationalisation. What happens for a user who has their PC configured in a different culture? The dates and numbers will get rendered differently - and will often break. That doesn't happen with parameters. Also: names often have apostrophes in :)
Do extend on #KirkWoll's very valid comment, any time you incorporate any user input (or input from automated sources for that matter) in a SQL statement, you place your program at risk of SQL injection.
As a matter of policy, you should never, ever build your own SQL statement using any such input.
Always sanitize input and always use parameterized queries as a first line of defense against SQL injection.
In case you have not seen it before, there's a great illustration on xkcd
http://xkcd.com/327/
Given that this is a WinForms program the only safe way to access the database is to use Stored Procedures that take parameters. Then create a user that only has access to those SPs. Anything else is not secure.
While queries with parameters work as a security measure when used with web applications which can have "attack" input, they fail when used with a local application which can be dis-assembled and re-written to anything. If you don't provide SP security you are lost.
Even though the user interaction may be a drop-down, it's possible for a sophisticated attacker to insert a value that is not in the list of selections. So YES, you should still be wary of SQL injection.
I would use prepared statements even if there was no such thing as SQL injection. They are just easier to use and in some cases they allow a database to cache the statement and not have to compile it the next time you use it. Oracle does that, I think SQL Server does, I don't know if MySQL does.
You should always assume that there are hackers, even on internal intranet projects, I use prepared statements and I use nonces to prevent CSRF.

How do I handle user submitted data to ensure best practice programming?

I would like to know what are the best practice programming tasks in relation to users submitting data through a web form to a website.
I am particularly interested in any C# or VB.NET commands that should be used through out the process from the moment the user hits the submit button until the data hits the database.
I have been reading about reasons why you may want to take precautions such as SQL injections etc.
Avoiding SQL injections is quite simple - just use parameterized queries, or an ORM such as LINQ to SQL or nHibernate (which all use parameters under the hood). The library takes care of everything for you, and has been thoroughly vetted.
After that, you're safe until it's time to write the data back out to other users. You always want to store the data as close to the original user input as possible. Another way to say this is - don't store a scrubbed version (unless you also store the original alongside it). Scrubbing is a one-way process - it destroys information. It's always easy to scrub again if you need to, but you can't un-scrub something.
However, storing the original format means you do need to make sure you encode the output before you write it to the browser. This prevents users from putting malicious cross-site scripts and other things into your data that might be rendered on other users' pages.
At the highest level, just keep in mind that all the work should be done as late as possible. Be liberal in what you accept (do only what is necessary to protect yourself) and strict in what you send (encode everything, scrub the hell out of it, transform it, etc). You want to have a "pure" copy which is altered to conform to the target output.
If you are serious about it read this book: 19 Deadly Sins of Software Security
Using linq2sql you get protection from SQL injection. Alternatively use .Parameters with parametrized queries.
When you send the data back on the page, you have to prevent the data from running js by encoding it. Use http://msdn.microsoft.com/en-us/library/w3te6wfz.aspx
And overall consider any of use of that data a chance for attack and look for ways to prevent it. For example, using user data as a filename to access/save something can mean access to unintended resources (by adding ..\).
You can't go wrong with the following general rules
Validate everywhere! Where you validate determines the quality of the user experience. The closer to the user, the less safe it is but more responsive. The farther away, the safer but tends to give worse error messages.
Validate at the front-end to give the user a responsive error.
Validate in the middle to give the user nicer error messages.
Validate in the database (constraints and such) to keep your database sane.
Use parameters early, and use them often! Find those square pegs early.
Coerce data into the correct types as quickly as possible. (This is a form of validation.) If something is an int, don't handle it like a string.
Don't throw away errors when checking parameters. If your regex doesn't match, or your try { parse } catch { } gets triggered it's important you know why and don't continue!
Whether you use LINQ or roll-your-own SQL: do not build SQL statements with user-supplied data. EVER. Use parameterized queries and/or stored procedure calls. If you must piece-together SQL as strings, don't do it with user data. Get the "untrustworthy" data stored and manipulate it as needed later, in a separate query.
Encode all data passed to the user. The bad data may not be their fault, don't trash their world.
Assume that anything they pass you is full of JavaScript and HTML. Assume that "binary" data will find its way in. Someone will run your web page on something other than a "browser" eventually. Your "phone number" field will be used to store an .EXE.
Return all data encoded and harmless. Don't assume that "because it's in the database" (or that it's an int, or that it's just a 1 character string) that it's harmless.
Assume that eventually your database will fail you somehow. A developer will drop in "test" data, you'll miss an edge case above, or something may run amok and insert all-purpose crap. This crap has to be passed to the user safely.
Nobody's perfect: especially you. Plan for that.
While pretty much all of the guidelines on the Open Web Application Security Project (OWASP) site are useful, here are their guidelines on data validation.

What are Some need to Know SQL Injection Techniques that Hackers use

I am tightening down my web application and I am on SQL right now. I already have sql parameters, doubling apostrophe, stripping javascript and encoding html. Is there other things I need to worry about besides the things above?
If you use Parameterized Queries, then you shouldn't need to do any of the stuff you describe in your post. This article seems to be a pretty good discussion about the subject.
To restate for emphasis, the silver-bullet for protecting against sql injection attacks is to only pass user input into sql via parameterized queries.
Parameterized queries are only needed if you are dynamically generating queries using data from the user.
There are benefits for using these queries on something like oracle, which is also useful.
Something else that you can do is to ensure that the user that connects to the database has the fewest privileges needed.
You can look here for some suggestions about protecting against sql injection:
http://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
Depending on your paranoia you can just use stored procedures to do that access, but that is more difficult if you need to make dynamic queries.
For select you can use views, that way it isn't possible, unless you have triggers on the view, to use that query to change any data in the database.
Another page that can be used is here:
http://www.wwwcoder.com/Directory/tabid/68/type/art/site/2966/parentid/258/Default.aspx
But, there is no point in putting more security than is reasonable, so you should weigh what you are protecting and how far to go.
For example, is it worth it to encrypt some of your columns? That leads to more issues as to how to protect keys, but, if you are worried about someone hacking into your machine and getting the database files that may be something to consider.
Technically Javascript and HTML have nothing to do with SQL injection attacks, but they are injection attacks.
I don't agree with stripping, at least not without informing the user that you have done so. For one, the actual input might actually be valid, removing certain characters might actually change the semantics of the input, and you normally can't be sure at storage time about every medium that the value might be rendered under. What about URL, LDAP, XML or File Path injection attacks.
You will find a lot of security "priests" (parrots I say) out there that argue that SQL injection is best protected by stripping the characters that can cause damage from the data entered. That is fine until fine as long as your not going to accept O'Brian as valid input for exmaple. It would have been better if they had preached about correct encoding, because all that effort might have been used to address a whole bunch of injection attacks.
Actually I once had to deal with code written by a MS security expert who wrote something like:
userInput = userInput.Replace( "--", "").Replace( "'", "");
In fairness to the fellow he is a very clever chap and I'm sure he wouldn't write this today, but can you see how "MyName -'- SELECT * FROM User" would actually get around this protection?
It's fine to have a range of characters you will accept and others that you won't as long as you don't block valid values. < is also a valid mathematical operator, or maybe the user needs to enter example HTML code. The context of the value determines what is valid and what isn't.
Then if you get a value including a character that is not allowed, display an error back to the user telling them about the invalid values and ask them to fix it before resending. This can save a lot of grief later, and this is as much about data validation and ensuring your program functions as it is about security. And yes you need to check this both at the client side to keep the traffic down and at the server side to prevent attacks.
And then whenever your render the value encode it appropriately. Parameterized queries are fine for solving SQL injection, but they don't work for rendering HTML, URL and javascript. Correct SQL encoding of values (you mentioned the double single quotes for example) is just as safe and in some cases preferable (assuming you have reasonable DBAs who don't insist that everything has to be Stored Procedures and allow correctly encoded dynamic SQL).
One other point, the System.Web HTML and URL encode functions have some flaws. There is a Microsoft team that produced the Anti Cross Site Scripting library which addresses these issues, and provides more specific encoding options. I think its called Anti-XSS or something like that. Definitely worth having a look at. I wonder if it got incorporated into .Net 4?
I'd recommend to download the automated Microsoft Source Code Analyzer for SQL Injection and let it analyze your code first, you may reap some cheap low hanging fruits.
Make sure all inputs are contained in quotes. If you have something like ... accepted=1 or age=30 ... you could possibly have a security hole there: ... accepted=1; DELETE....
EDIT: Yes the attacker could use 1"; DELETE, but that doesn't work with escaped input.
A cyberpunk can get a perl shell from the uri query via concatenation. 3 solutions are use stored procedures, preparedstatements or gql instead.
Parameterized queries go a long ways towards keeping the baddies out, but make sure there aren't strange, injectable dynamic sql concoctions behind them opening new vulnerabilities.
Other, lunatic fringe idea: don't run popular open source packages, especially those written in languages starting with P.

Categories

Resources