Monday, July 28, 2008

Export to Excel Using Styles

Saturday, July 19, 2008

Encrypting QueryStrings with .NET

Introduction:

Once upon a time in the tech world, obscurity was security - this being most true in the early years of the industry, when there were gaping holes in privacy policies and confidential client information was bandied about from site to site without a care as to who actually could read the information.

With the new Cryptography classes in .NET, there's absolutely no excuse for not hiding even the most innocuous user data. If you ever need to 'piggy-back' information from one web page to another, whether it is within a POST or a GET parameter, you're passing clear information that anyone can sniff - and that's a bad thing.

If you're not going to use a session variable for storing end user information, you're most likely going to keep some sort of State by passing the information to a cookie or push it around with GET/POST parameters. If you're passing around any sort of ID or user information like their name, it's better to err on the side of caution and encrypt the information.

GET Vs. POST

A POST parameter keeps the information out of the URL, but it can still be sniffed quite easily as it passes in clear text across your network or the Internet. Using POST will keep the mere curious at bay, as the information is not contained in the URL - but this will not stop someone determined to snag out your data.

A QueryString parameter passes information within the site's URL. Why would you even use a QueryString? Well, maybe you need to let your user bookmark a particular page, or maybe you have to refer directly to a page in a URL via a link - you can't do either if you're using POST. A QueryString puts data in the URL for the entire world to see, so if you don't know if the end user is malicious, I'd think hard about using a QueryString for anything but site-related information.
Be smart and encrypt any and all data you're moving around from page to page, especially if that information could be used maliciously. You may trust your users, but you still need that extra level of security that clear text GET/POST data doesn't provide.

Imagine this scenario - you've been passing the customer's ID in the database around in a QueryString, in a URL that looks like this:
http://mysite.com?cust_id=29

You know what a user is going to do? Switch that 29 to a 30 or 12 or some other number, and if you're not checking for invalid requests, you'll be dishing up some other customer's data.

Enter Encryption

What I was looking for was a quick way to encrypt and decrypt parts of a QueryString - it had to be on the fly, quick and dirty.
I chose Base64 because it wouldn't throw bizarre characters in my QueryString that I couldn't pass around… Little did I know that I'd hit a snag while passing around my encrypted QueryString - Apparently, the Request.QueryString object interprets the '+' sign as a space! So, with a quick Replace function slapped on my decrypt string, no harm, no foul.

Symmetric Key

The whole trick to this working is that the QueryString is encrypted and decrypted with the same private key. This is the secret key - if anyone gets a hold of your key, they can decrypt the data themselves, so keep it a secret!
We're going to use a hard-to-crack 8 byte key, !#$a54?3, to keep parts of our QueryString secret. Let's Walk through the C# portion of the code:

Notice our two functions that abstract the dirty work that our Encryption64 class. The first, encryptQueryString, is used to encrypt the value of a QueryString. The second, decryptQueryString, is used to decrypt the value of an encrypted QueryString.

public string encryptQueryString(string strQueryString) {
ExtractAndSerialize.Encryption64 oES =
new ExtractAndSerialize.Encryption64();
return oES.Encrypt(strQueryString,"!#$a54?3");
}

public string decryptQueryString(string strQueryString) {
ExtractAndSerialize.Encryption64 oES =
new ExtractAndSerialize.Encryption64();
return oES.Decrypt(strQueryString,"!#$a54?3");
}

If we wanted to encrypt our QueryString on our first page, we could do something like this:
string strValues = "search term";
string strURL = "http://mysite.com?search="
+ encryptQueryString(strValues);
Response.Redirect(strURL);

Inside our code-behind in our second page, we pass the contents our QueryString to a variable named strScramble. After that, we replace the '+' signs that our wonderful Request.QueryString has replaced with a space. We pass that string into our function, decryptQueryString, and retrieve the decrypted string.

string strScramble = Request.QueryString["search"];
string strdeCrypt = decryptQueryString(
strScramble.Replace(" ", "+"));

Now we've decrypted the value of the QueryString, 'search', and we can do whatever we want with it. The end user is going to see a URL that looks like:
http://yoursite.com?search=da00992Lo39+343dw

They'll never be able guess what's going on in your QueryString, and if they try to fool around with it, there's no way to crack the code without knowing the Symmetric key.

C#.NET
1. using System;
2. using System.IO;
3. using System.Xml;
4. using System.Text;
5. using System.Security.Cryptography;
6.
7. public class Encryption64
8. {
9. private byte[] key = {};
10. private byte[] IV = {18, 52, 86, 120, 144, 171, 205, 239};
11.
12. public string Decrypt(string stringToDecrypt, string sEncryptionKey)
13. {
14. byte[] inputByteArray = new byte[stringToDecrypt.Length + 1];
15. try {
16. key = System.Text.Encoding.UTF8.GetBytes(Strings.Left(sEncryptionKey, 8));
17. DESCryptoServiceProvider des = new DESCryptoServiceProvider();
18. inputByteArray = Convert.FromBase64String(stringToDecrypt);
19. MemoryStream ms = new MemoryStream();
20. CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(key, IV), CryptoStreamMode.Write);
21. cs.Write(inputByteArray, 0, inputByteArray.Length);
22. cs.FlushFinalBlock();
23. System.Text.Encoding encoding = System.Text.Encoding.UTF8;
24. return encoding.GetString(ms.ToArray());
25. }
26. catch (Exception e) {
27. return e.Message;
28. }
29. }
30.
31. public string Encrypt(string stringToEncrypt, string SEncryptionKey)
32. {
33. try {
34. key = System.Text.Encoding.UTF8.GetBytes(Strings.Left(SEncryptionKey, 8));
35. DESCryptoServiceProvider des = new DESCryptoServiceProvider();
36. byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToEncrypt);
37. MemoryStream ms = new MemoryStream();
38. CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(key, IV), CryptoStreamMode.Write);
39. cs.Write(inputByteArray, 0, inputByteArray.Length);
40. cs.FlushFinalBlock();
41. return Convert.ToBase64String(ms.ToArray());
42. }
43. catch (Exception e) {
44. return e.Message;
45. }
46. }
47.
48. }
49.

Friday, July 18, 2008

Finding If the Url Exists

Introduction:
Hyperlinks are the linking blocks of all web applications. You can link one webpage to the other by using hyperlinks. Sometimes when a website contains hundreds of links it is hard to locate that which links are working and which are not. In this article I will demonstrate that how you can find out that if the hyperlink of a webpage is exists or not.
Getting all the urls of the Page:
Our first task is to get all the urls (hyperlinks) on the page. Once, we have all the hyperlinks contained in a webpage we can iterate through the links and find out which of them exists. Check out the code below which demonstrates that how you can extract the HTML of a page.
 List badUrlList = new List();
        WebRequest req = WebRequest.Create("http://

localhost:2640/BadUrls/UrlList.aspx");
        HttpWebResponse res = (HttpWebResponse)req.GetResponse();
        Stream stream = res.GetResponseStream();
        ArrayList badUrls = 
new ArrayList();

        StreamReader reader = 
new StreamReader(stream);
        
string html = reader.ReadToEnd();
 

 The WebRequest class contains the Create method which makes the request to provided url. The GetResponse method is used to get the response from the web server. After getting the response we read the ResponseStream in the string format and save the output in a string variable called "html".
The string variable "html" will contain all the HTML tags of the requested page. At this point we need to extract the links out of the HTML. For this we will need a regular expression. Check out the code below which uses a regular expression to extract all the links out of the HTML of the page.
 // Get the links
        
string pattern = @"((http|ftp|https):\/\/w{3}[\d]*.|

(http|ftp|https):\/\/|w{3}[\d]*.)([\w\d\._\-#\(\)\[\]\\,;:]
+@[\w\d\._\-#\(\)\[\]\\,;:])?([a-z0-9]+.)*[a-z\-0-9]+.([a-z]
{2,3})?[a-z]{2,6}(:[0-9]+)?(\/[\/a-z0-9\._\-,]+)*[a-z0-9\-_\
.\s\%]+(\?[a-z0-9=%&\.\-,#]+)?";

        Regex r = 
new Regex(pattern);
        MatchCollection mC = r.Matches(html);

The MatchCollection variable "mC" will contain all the matches of the regular expression. In this case mC will be filled with all the hyperlinks. Now, we can check the hyperlinks one by one and find out that if it exists or not.
Making Sure that the Hyperlink Exists:
First, I must admit that the method that I am going to use is not the best method. Second, the method when executed takes awful amount of time and can result in a timeout. Also, this method will not work if your ISP is redirecting you to a custom page when the page not found exception is thrown.
 private bool DoesUrlExists(string url)
    {
        
bool urlExists = false;
    

        
try
        
{

            WebRequest req = WebRequest.Create(url);
            HttpWebResponse response = (HttpWebResponse)req.GetResponse();
            urlExists = 
true;
        }
        
catch (System.Net.WebException ex)
        {
       
        }

        
return urlExists;
    }

 As, you can see from the code above that the whole logic is based on the exceptions. If the exception is thrown then it will be assumed that the url does not exists else the url exists.
I made a simple test file to make sure that the application works as expected. Take a look at the file below which have some real urls and some dummy urls.
UrlList.aspx:



     My Url
    My Url
    My Url
    My Url
    


I have also made the interface a little better so that the user will have a better idea of what is happening.
 
The urls which are highlighted in dark pink are the urls that does not exists and the ones in the light green are the ones which exists. As, you can see that the application shows that the urls www.jhasd.aspx and www.bhbbagsdns.aspx exists but in reality they do not exist. The reason the dummy links are showing as exist is that the ISP is redirecting the page not found requests to a custom page which exists. My suggestion is that when you are running this application make sure that the page not found requests are not redirected to the custom ISP page.
I have included the download samples files which can be downloaded at the end of this article.
I hope you liked the article, happy coding!

Prevent Caching of WebPage in Asp.net

Prevent Caching of .aspx page

private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetAllowResponseInBrowserHistory(false);
}
}

URL Mapping in asp.net 2.0

URL Mapping is a mechanism by which you can change the displayed url in address bar.
Example:
Your asp.net application is developed from years, with convention frm as prefix to webform.
Now to change already assigned name to legacy system which is maintained for past few years and to avoid risk we can make use of URL Mapping.

For URL Mapping
Step1: Add Mapping URL in web.config file.
<system.web>
<
urlMappings enabled="true">
<add url="~/Department.aspx" mappedUrl=" oldforms/frmDept.aspx"/>
<add url="~/Employee.aspx" mappedUrl=" oldforms/frmEmployee.aspx"/>
<add url="~/Product.aspx" mappedUrl=" oldforms/frmProduct.aspx"/>
urlMappings>
system.web>

Step2: Change the URL in .aspx file
<a href="Department.aspx">Departmenta><br />
<a href="Product.aspx">Producta><br />
<a href="Employee.aspx">Employeea>

Stock Quote & Currency Convertor Using Web service

http://www.webservicex.net/stockquote.asmx?WSDL

http://www.webservicex.net/CurrencyConvertor.asmx?WSDL

Guard Against SQL Injection Attacks

SQL Injection attacks are really nasty security vulnerabilities, and something all web developers (regardless of platform, technology or data layer) need to make sure they understand and protect themselves against.  Unfortunately developers too often neglect putting focused time on this - and leave their applications (and worse their customers) extremely vulnerable.
Michael Sutton recently published a very sobering post about just how widespread this issue is on the public web.  He built a C# client application that uses the Google Search API to look for sites vulnerable to SQL Injection Attacks.  The steps to achieve this were simple:

  1. Look for sites that have querystring values (example: search for URLs with "id=" in the URL)
  2. Send a request to the sites identified as dynamic with an altered id= statement that adds an extra quote to attempt to cancel the SQL statement (example: id=6')
  3. Parse the response sent back to look for words like "SQL" and "query" - which typically indicate that the app is often sending back detailed error messages (also bad)
  4. Review whether the error message indicates that the parameter sent to SQL wasn't encoded correctly (in which case the site is open to SQL Injection Attacks)
Of a random sampling of 1000 sites he found via his Google search, he detected possible SQL Injection Attack vulnerability with 11.3% of them.  That is really, really scary.  It means hackers can remotely exploit the data in those applications, retrieve any unhashed/encrypted passwords or credit-card data, and potentially even log themselves in as administrators to the application.  This is bad not only for the developer who built the application, but even worse for any consumer/user of the application who has provided data to the site thinking it will be secure.
So what the heck is a SQL Injection Attack?
There are a couple of scenarios that make SQL Injection attacks possible.  The most common cause are cases where you are dynamically constructing SQL statements without using correctly encoded parameters.  For example, consider this SQL query code that searches for Authors based on a social security number provided via a querystring:

Dim SSN as String
Dim 
SqlQuery as String

SSN Request.QueryString("SSN")
SqlQuery 
"SELECT au_lname, au_fname FROM authors WHERE au_id = '" + SSN + "'"
If you have SQL code like the snippet above, then your entire database and application can be hacked remotely.  How?  Well in the normal scenario users will hit the site using a social security number which will be executed like so:

' URL to the page containing the above code
http://mysite.com/listauthordetails.aspx?SSN=172-32-9999

' SQL Query executed against the database
SELECT au_lname, au_fname FROM authors WHERE au_id '172-32-9999'
This does what the developer expected, and searches the database for author information filtered by the social security number.  But because the parameter value hasn't been SQL encoded, a hacker could just as easily modify the querystring value to embed additional SQL statements after the value to execute.  For example:

' URL to the page containing the above code
http://mysite.com/listauthordetails.aspx?SSN=172-32-9999';DROP DATABASE pubs --

' SQL Query executed against the database
SELECT au_lname, au_fname FROM authors WHERE au_id = '';DROP DATABASE pubs --
Notice how I was able to add the ';DROP DATABASE pubs -- clause to the SSN querystring value and use it to terminate the current SQL statement (via the ";" character), and then add my own malicious SQL statement to the string, and then comment out the rest of the statement (via the "--" characters).  Because we are just manually concatenating the SQL statement in our code, we will end up passing this to the database - which will execute first the query against the authors table, and then delete our pubs database table.  Bang - it is now gone.
In case you think the idea of anonymous hackers deleting your database tables is bad, that is unfortunately actually one of the better scenarios when a SQL Injection Attack is involved.  Rather than just destroy data, a hacker could instead use the above code vulnerability to perform a JOIN that retrieves all of the data within your database and displays it on the page (allowing them to retrieve username/passwords/credit-cards).  They could also add UPDATE/INSERT statements to modify product prices, add new admin users, and really screw up your life (imagine auditing your inventory at the end of the month, only to discover that the actual number of products in your warehouse is different then what your accounting system reports...). 
How do you protect yourself?
SQL Injection Attacks are something you need to worry about regardless of the web programming technology you are using (all web frameworks need to worry about it).  A couple of very basic rules you must always follow:
1) Don't construct dynamic SQL Statements without using a type-safe parameter encoding mechanism.  Most data APIs (including ADO + ADO.NET) have support for allowing you to specify the exact type of a parameter being provided (for example: string, integer, date) and can ensure that they are escaped/encoded for you to avoid hackers trying to exploit it.  Always use these features
For example, with dynamic SQL using ADO.NET you could re-write the code above like below to make it safe:

Dim SSN as String Request.QueryString("SSN")

Dim cmd As 
new SqlCommand("SELECT au_lname, au_fname FROM authors WHERE au_id = @au_id")
Dim param 
= new SqlParameter("au_id", SqlDbType.VarChar)
param.Value 
SSN
cmd.Parameters.Add(param)
This will prevent someone from trying to sneak in additional SQL expressions (since ADO.NET above knows to string encode the au_id value), and avoid other data problems (incorrectly type-casting values, etc).  Note that the TableAdapter/DataSet designer built-into VS 2005 uses this mechanism automatically, as do the ASP.NET 2.0 data source controls. 
One common misperception is that if you are using SPROCs or a ORM you are completely safe from SQL Injection Attacks.  This isn't true - you still need to make sure you are careful when you pass values to a SPROC, and/or when you escape or customize a query with an ORM that you do it in a safe way.
2) Always conduct a security review of your application before ever put it in production, and establish a formal security process to review all code anytime you make updates.  This later point is super important.  Too often I hear of teams that conduct a really detailed security review before going live, then have some "really minor" update they make to the site weeks/months later where they skip doing a security review ("it is just a tiny update - we'll code review it later").  Always do a security review.
3) Never store sensitive data in clear-text within a database.  My personal opinion is that passwords should always be one-way hashed (I don't even like to store them encrypted).  The ASP.NET 2.0 Membership API does this for you automatically by default (and also implements secure SALT randomization behavior).  If you decide to build your own membership database store, I'd recommend checking out the source code for our own Membership provider implementation that we published here.  Also make sure to encrypt credit-card and other private data in your database.  This way even if your database was compromised, at least your customer private data can't be exploited.
4) Ensure you write automation unit tests that specifically verify your data access layer and application against SQL Injection attacks.  This is really important to help catch the "it is just a tiny update so I'll be safe" scenario, and provide an additional safety layer to avoid accidentally introducing a bad security bug into your application.
5) Lock down your database to only grant the web application accessing it the minimal set of permissions that it needs to function.  If the web application doesn't need access to certain tables, then make sure it doesn't have permissions to them.  If it is only read-only generating reports from your account payables table then make sure you disable insert/update/delete access. 

App_Offline.htm

App_Offline.htm 

Basically, if you place a file with this name in the root of a web application directory, ASP.NET 2.0 will shut-down the application, unload the application domain from the server, and stop processing any new incoming requests for that application.  ASP.NET will also then respond to all requests for dynamic pages in the application by sending back the content of the app_offline.htm file (for example: you might want to have a “site under construction” or “down for maintenance” message).
This provides a convenient way to take down your application while you are making big changes or copying in lots of new page functionality (and you want to avoid the annoying problem of people hitting and activating your site in the middle of a content update).  It can also be a useful way to immediately unlock and unload a SQL Express or Access database whose .mdf or .mdb data files are residing in the /app_data directory.
Once you remove the app_offline.htm file, the next request into the application will cause ASP.NET to load the application and app-domain again, and life will continue along as normal.