Simple Linq Security - c#

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.

Related

DDD - transient validation using an aggregate

I have a particular scenario where an aggregate has behavior to check whether an address is valid. This validation is triggered on the aggregate via inline ajax form validation on a web site. In between the aggregate and the web site is an application service which orchestrates the two.
As it stands, I create what is essentially an empty aggregate and set the address property so the check can be done. Based on this I return true or false back to the web site (ASP.NET MVC). This doesn't seem like the right approach on the context of DDD.
public bool IsAddressAvailable(string address)
{
var aggregate = new Aggregate
{
Address = address
};
return aggregate.IsAddressValid();
}
What options do I have that would work better using DDD? I was consider separating it out into a domain service. Any advice would be appreciated!
Normally your aggregates should not expose Get- methods, you always want to follow Tell-Don't-Ask principle.
If something needs to be done - then you call an aggregate method and it makes it done.
But you normally don't want to ask Aggregate if the data is valid or not. Especially if you already have a service that does this job for you, why mixing this "validation" with aggregates?
The rule of thumb is:
If something is not needed for Aggregate's behavior it doesn't need to be a part of the aggregate
You only pass valid data into your domain. It means that when you call an aggregate behavior asking it to do something for you, the data you pass is already validated. You don't want to pollute your domain with data validation / if-else branches, etc. Keep it straight and simple.
In your case, as far as I understand, you only need to validate user's input, so you don't need to bother your domain to do it for two reasons:
You don't do anything, don't change system's state. It is considered to be a "read" operation, do it straightforward (call your service, validate against some tables, etc)
You cannot rely on validation result. Now it tells you "correct" and in 10 milliseconds (while you get the response over the wire, while HTML is rendered in browser, etc) it is already a history, it MAY change any time. So this validation is just a guidance, no more.
Therefore if you only need "read-only" validation just do it against your service.
If you need to validate user's data as a part of operation then do it before you call the domain (perhaps in your command handler).
And be aware of racing conditions (DB unique constraints can help).
You should also consider reading this to think deeper about set validation: http://codebetter.com/gregyoung/2010/08/12/eventual-consistency-and-set-validation/

Spreading of business logic between DB and client

Ok guys, another my question is seems to be very widely asked and generic. For instance, I have some accounts table in my db, let say it would be accounts table. On client (desktop winforms app) I have appropriate functionality to add new account. Let say in UI it's a couple of textboxes and one button.
Another one requirement is account uniqueness. So I can't add two same accounts. My question is should I check this account existence on client (making some query and looking at result) or make a stored procedure for adding new account and check account existence there. As it for me, it's better to make just a stored proc, there I can make any needed checks and after all checks add new account. But there is pros and cons of that way. For example, it will be very difficult to manage languagw of messages that stored proc should produce.
POST EDIT
I already have any database constraints, etc. The issue is how to process situation there user is being add an existence account.
POST EDIT 2
The account uniqueness is exposed as just a simple tiny example of business logic. My question is more abour handling complicated business logic on that accounts domain.
So, how can I manage this misunderstanding?
I belive that my question is basic and has proven solution. My tools are C#, .NET Framework 2.0. Thanks in advance, guys!
If the application is to be multi-user ( i.e. not just a single desktop app with a single user, but a centralised DB with the app acting as clients maybe on many workstations), then it is not safe to rely on the client (app) to check for such as uniqueness, existance, free numbers etc as there is a distinct possibility of change happening between calls (unless read locking is used, but this often become more of an issue than a help!).
There is the ability of course to precheck and then recheck (pre at app level, re at DB), but of course this would give extra DB traffic, so depends on whether it is a problem for you.
When I write SPROCs that will return to an app, I always use the same framework - I include parameters for a return code and message and always populate them. Then I can use standard routines to call them and even add in the parameters automatically. I can then either display the message directly on failure, or use the return code to localize it as required (or automate a response). I know some DBs (like SQL Svr) will return Return_Code parameters, but I impliment my own so I can leave inbuilt ones for serious system based errors and unexpected failures. Also allows me to have my own numbering systems for return codes (i.e. grouping them to match Enums in the code and/or grouping by severity)
On web apps I have also used a different concept at times. For example, sometimes a request is made for a new account but multiple pages are required (profile for example). Here I often use a header table that generates a hidden user ID against the requested unique username, a timestamp and someway of recognising them (IP Address etc). If after x hours it is not used, the header table deletes the row freeing up the number (depending on DB the number may never become useable again - this doesn;t really matter as it is just used to keep the user data unique until application is submitted) and the username. If completed correctly, then the records are simply copied across to the proper active tables.
//Edit - To Add:
Good point. But account uniqueness is just a very tiny simple sample.
What about more complex requirements for accounts in business logic?
For example, if I implement in just in client code (in winforms app) I
will go ok, but if I want another (say console version of my app or a
website) kind of my app work with this accounts I should do all this
logic again in new app! So, I'm looking some method to hold data right
from two sides (server db site and client side). – kseen yesterday
If the requirement is ever for mutiuse, then it is best to separate it. Putting it into a separate Class Library Project allows the DLL to be used by your WinForm, Console program, Service, etc. Although I would still prefer rock-face validation (DB level) as it is closest point in time to any action and least likely to be gazzumped.
The usual way is to separate into three projects. A display layer [DL] (your winform project/console/Service/etc) and Business Application Layer [BAL] (which holds all the business rules and calls to the DAL - it knows nothing about the diplay medium nor about the database thechnology) and finally the Data Access Layer [DAL] (this has all the database calls - this can be very basic with a method for insert/update/select/delete at SQL and SPROC level and maybe some classes for passing data back and forth). The DL references only the BAL which references the DAL. The DAL can be swapped for each technology (say change from SQL Server to MySQL) without affecting the rest of the application and business rules can be changed and set in the BAL with no affect to the DAL (DL may be affected if new methods are added or display requirement change due to data change etc). This framework can then be used again and again across all your apps and is easy to make quite drastic changes to (like DB topology).
This type of logic is usually kept in code for easier maintenance (which includes testing). However, if this is just a personal throwaway application, do what is most simple for you. If it's something that is going to grow, it's better to put things practices in place now, to ease maintenance/change later.
I'd have a AccountsRepository class (for example) with a AddAcount method that did the insert/called the stored procedure. Using database constraints (as HaLaBi mentioned), it would fail on trying to insert a duplicate. You would then determine how to handle this issue (passing a message back to the ui that it couldn't add) in the code. This would allow you to put tests around all of this. The only change you made in the db is to add the constraint.
Just my 2 cents on a Thrusday morning (before my cup of green tea). :)
i think the answer - like many - is 'it depends'
for sure it is a good thing to push logic as deeply as possible towards the database. This prevent bad data no matter how the user tries to get it in there.
this, in simple terms, results in applications that TRY - FAIL - RECOVER when attempting an invalid transaction. you need to check each call(stored proc, or triggered insert etc) and IF something bad happens, recover from that condition. Usually something like tell the user an issue occurred, reset the form or something, and let them try again.
i think at a minimum, this needs to happen.
but, in addition, to make a really nice experience for the user, the app should also preemptively check on certain data conditions ahead of time, and simply prevent the user from making bad inserts in the first place.
this is of course harder, and sometimes means double coding of business rules (one in the app, and one in the DB constraints) but it can make for a dramatically better user experience.
The solution is more of being methodical than technical:
Implement - "Defensive Programming" & "Design by Contract"
If the chances of a business-rule being changed over time is very less, then apply the constraint at database-level
Create a "validation or rules & aggregation layer (or class)" that will manage such conditions/constraints for entity and/or specific property
A much smarter way to do this would be to make a user-control for the entity and/or specific property (in your case the "Account-Code"), which would internally use the "validation or rules & aggregation layer (or class)"
This will allow you to ensure a "systematic-way-of-development" or a more "scalable & maintainable" application-architecture
If your application is a website then along with placing the validation on the client-side it is always better to have validation even in the business-layer or C# code as well
When ever a validation would fail you could implement & use a "custom-error-message" library, to ensure message-content is standard across the application
If the errors are raised from database itself (i.e., from stored-procedures), you could use the same "custom-error-message" class for converting the SQL Exception to the fixed or standardized message format
I know that this is all a bit too much, but is will always good for future.
Hope this helps.
As you should not depend on a specific Storage Provider (DB [mysql, mssql, ...], flat file, xml, binary, cloud, ...) in a professional project all constraint should be checked in the business logic (model).
The model shouldn't have to know anything about the storage provider.
Uncle Bob said something about architecture and databases: http://blog.8thlight.com/uncle-bob/2011/11/22/Clean-Architecture.html

Best Way to Prevent SQL Injection Using Javascript or 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

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