views:

101

answers:

4

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.

+4  A: 

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.

Rex M
@Anon why the DV?
Rex M
+3  A: 

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 ..\).

eglasius
+1  A: 

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.

clintp
Your first and last lines seem mutually exclusive: "You can't go wrong..." and "Nobody's perfect..."
Argalatyr
@Argalatyr lol!
eglasius
I guess you were either trying to be funny or you missed the point.Do as much of this list as possible, because some of it you will screw up. Your mistakes in one part may caught elsewhere.
clintp
@clintp: I'm sincerely sorry I forgot to add a smiley, and am grateful that Freddy realized I did not mean to come off negatively. Just seemed a funny juxtaposition.
Argalatyr
+2  A: 

Others have commented on some C# specific stuff. 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.

Sterno
not c# specific, .net specific ;) ... that said, things we mentioned are general, we just included the .net specific things i.e. parametrized queries, encode output, avoid using user input as filenames and a link to a book that isn't .net specific :) ... all that said, +1 that's a link with nice info
eglasius