mustcodemore.com

9.26.2007

SQLSafe Method for C#

We created this utility method a while back to help us provide another layer of security for SQL Injection attacks. Basically its a tiny little method that takes up to three parameters. It is used to trim a string to a specified length (generally the length of your database field) and throw an error if you want it too.

Parm 1. The string to evaluate and trim if necessary
Parm 2. The max length of the string
Parm 3. Thow an exception or not.

Heres the two methods (one with an override)

        /// <summary>
/// Returns a string with single quotes escaped to protect against SQL injection attacks
///
/// This method will throw an exception if the supplied string's length is greater than maxlen
/// </summary>
/// <param name="s"></param>
/// <param name="maxlen"></param>
/// <returns></returns>
public static string SqlSafe(string s,int maxlen)
{
return SqlSafe(s,maxlen,false);
}
/// <summary>
/// Returns a string with single quotes escaped to protect against SQL injection attacks
///
/// </summary>
/// <param name="s"></param>
/// <param name="maxlen"></param>
/// <param name="ThrowExceptionOnTruncate"></param>
/// <returns></returns>
public static string SqlSafe(string s,int maxlen,bool ThrowExceptionOnTruncate)
{
if(s==null)
{
return "";
}
if(ThrowExceptionOnTruncate && s.Length>maxlen)
{
throw new Exception("StringTools.SqlSafe string exceeds maximum length");
}
//replace apostrophies AFTER truncation
//(the doubles don't count for field length)
return Truncate(s,maxlen).Replace("'","''");
}


So this method is called from anywhere (usually i put it right in a parameter going to a SQL DataSource or some Object Data source right before insert or update).
Just call it like this

SBX.StringTools.SqlSafe(HttpContext.Current.Request.UserAgent.ToString(), 255);


In this example i have the SqlSafe method in a static class called SBX.StringTools. If you are going to use this put it in whatever framework class libraries you utilize in your web or forms apps. That way you can re-use it quickly and easily.

mcm.

My Goodness - Blogger Code Formatting!

And its IN a Blogger Blog! Doesn't that just blow your mind?

http://formatmysourcecode.blogspot.com/

How to tell if a posted file is really an image

This is a useful method to determine if a file posted for upload (via HTTP) is actually an image. This was created in .net 1.1 but also works in 2.0 without any modifications.

Heres a bit of background. Anyone can change the content type of a file before posting it. Its as simple as changing an extension of a file to something your looking for. So if someone wanted to upload a malicious program or file they could simply change the extension to an images extension (in this case) and upload something that .net initially thinks is an image but really is not.

All this method does is read the first 64 bytes of data from the posted file and compares the data in the header to determine if its an image. It takes a byte array as an input and returns either true or false to the calling method.

public bool IsImage(byte[] data)
{
//read 64 bytes of the stream only to determine the type
string myStr = System.Text.Encoding.ASCII.GetString(data).Substring(0, 16);
//check if its definately an image.
if (myStr.Substring(8, 2).ToString().ToLower() != "if")
{
//its not a jpeg
if (myStr.Substring(0, 3).ToString().ToLower() != "gif")
{
//its not a gif
if (myStr.Substring(0, 2).ToString().ToLower() != "bm")
{
//its not a .bmp
if (myStr.Substring(0, 2).ToString().ToLower() != "ii")
{
myStr = null;
return false;
}
}
}
}
myStr = null;
return true;
}


Thats really all there is to it. Once this is in place you can actually add more if statements to look for more image types (like .tiff, etc). The reason we dont use a switch statement for this is because for different image formats the "identifying byte(s)" are located in different index positions. So to add more images you will have to dig around the net a bit finding out about what header bytes identify different images.

hope this helps someone out,
mcm.

ASP.NET 2.0 Roles and Memberships

ASP.NET's Role management and membership providers are really, really easy to use and configure (once you figure out how to set up the database)

This article from 4Guys really helped me set it up properly and now that its up its quite easy to port and use for other applications. The design of it actually lets you use one Database to manage security and roles for several applications.

The only unfortunate part about these Roles and membership things is that the default web controls (specifically LoginView) are not really scalable. If you plan on having an ever growing list of roles and users you may not want to use these types of controls and instead programmaticlly control access to pages and page elements (see gridviews / formviews). This can be done pretty easily with the use of a secured page base class that you can inherit from.

Anyways, check the article http://aspnet.4guysfromrolla.com/articles/120705-1.aspx

mcm.

Image Uploading to a UNC Share w/ Impersonation

This topic has helped me countless times. Think about full separation of an admin area from a front-end site. If you have to upload images this is a good way to go about it. It's really either this way or some sort of service that copies uploaded images to the other app directory.

http://aspalliance.com/336

GROUP BY in a DataTable

this one helped me out a while back
http://weblogs.sqlteam.com/davidm/archive/2004/05/20/1351.aspx

The Expressions that can be formulated for a calculated column in a DataTable are a very handy thing. The problem is the aggregation operators only work for a parent-child relationship.

Optimizing ASP.NET 2.0 Web Project Build Performance (VS 2005)

This posts covers how to best optimize the build performance with Visual Studio 2005 when using web projects. If you are experiencing slow builds or want to learn how to speed them up please read on.

http://weblogs.asp.net/scottgu/archive/2006/09/22/Tip_2F00_Trick_3A00_-Optimizing-ASP.NET-2.0-Web-Project-Build-Performance-with-VS-2005.aspx