Michael Falconer

the difficult takes time, the impossible just a little longer

My Links

Blog Stats

News

Michael Falconer is a freelance/contract .net developer working in and around Glasgow, Scotland, mainly on asp.net applications. His company is called, for some strange reason, Camel-Jones.

Archives

Post Categories

Blogs

Other Links

Regulars

Wednesday, May 18, 2005 #

Threat Modeling Web Applications

Well, felt it was finally time to start posting again. I've been working on quite a few interesting applications over the past few months, so I hope to add some useful posts soon.

In the meantime there's an interesting new series of posts on MSDN about developing threat models for web applications. While you may be aware of most of the threats, and the steps to prevent them becoming attacks, it's always good to review your knowledge, and to read about formalising the processes you hopefully already go through.

posted @ 1:28 PM

Sunday, February 13, 2005 #

ViewStateUserKey

While reading through an article titled 'Take Advantage of ASP.NET Built-in Features to Fend Off Web Attacks' on MSDN recently, I came across a new property for the Page class I'd never noticed before: ViewStateUserKey. The documentation for this property states:

Assigns an identifier to an individual user in the view state variable associated with the current page

It turns out what this can be used for is to add a user specific string to the ViewState of a Page which can be verified on PostBack. Why? This means you can be sure that any form information submitted came from the same user who requested the original page, thus preventing one-click attacks.

I highly recommend you read the article above for more information, and for techniques to prevent other common attacks...

posted @ 12:04 PM

Monday, January 31, 2005 #

Enterprise Library Released

As pointed out by Roy Osherove, the new Enterprise Library for .net has been released. It basically encapsulated the application blocks that were previously released separately:

  • Caching Application Block
  • Configuration Application Block
  • Data Access Application Block
  • Cryptography Application Block
  • Exception Handling Application Block
  • Logging and Instrumentation Application Block
  • Security Application Block

It may only be a 'stopgap' until the launch of .net v2, but I for one am planning to make use of it. I've been making use of four of the blocks, and have been looking forward to an update that fixes many of the known issues. So I'll let you know how I get on with it.

You can download it from MSDN.

posted @ 1:59 PM

Friday, November 26, 2004 #

Website Accessiblity - Simulating Colour Blindness

Ever wondered how your site looks to someone who is colourblind? Then try the Vischeck on a webpage. It's free and, with 1 in 20 people having some sort of colour vision deficiency, makes for interesting viewing.

Here's how this site looks:

posted @ 11:49 AM

Wednesday, November 10, 2004 #

.Net helper class for SQL Server Full Text Search

I've made use of SQL Servers ability to run a full text search in a couple of projects recently and wrote a little helper class that takes a typical search phrase and creates the tsql statement that you can then pass into a CONTAINSTABLE clause. Basically it looks either for words separated by a space, or a phrase with quotes around it, or a mixture of both.

There is one limitation in this implementation; the noise words are hard coded into a string array. It would be better to read in the contents of the noise word file that SQL Server uses, but in some shared hosting arrangements you may not have access to the file.

    1 using System;
    2 using System.Collections;
    3  
    4 namespace CamelJones.Data.Utils
    5 {
    6   /// <summary>
    7   /// Helper object for converting a search string into a
    8   /// Full Text Search query, used in a CONTAINSTABLE clause.
    9   /// </summary>
   10   public class SqlFtsHelper
   11   {
   12     #region Private Members
   13  
   14     private string _searchPhrase;
   15     private string _ftsQuery;
   16     private ArrayList _ignoredWords = new ArrayList();
   17     private string[] _noiseWords = new string[] {"about","after","all","also","an","and","another","any","are","as","at","be","because","been","before","being","between","both","but","by","came","can","come","could","did","do","each","for","from","get","got","has","had","he","have","her","here","him","himself","his","how","if","in","into","is","it","like","make","many","me","might","more","most","much","must","my","never","now","of","on","only","or","other","our","out","over","said","same","see","should","since","some","still","such","take","than","that","the","their","them","then","there","these","they","this","those","through","to","too","under","up","very","was","way","we","well","were","what","where","which","while","who","with","would","you","your"};
   18  
   19     #endregion
   20  
   21     #region Constructors
   22  
   23     /// <summary>
   24     /// Constructor for the SqlFtsHelper object
   25     /// </summary>
   26     /// <param name="query">The search string that is to be used to create the Full Text Search query</param>
   27     public SqlFtsHelper(string searchPhrase)
   28     {
   29       _searchPhrase = searchPhrase;
   30       BuildFTSQuery();
   31     }
   32  
   33     #endregion
   34  
   35     #region Public Methods
   36  
   37     /// <summary>
   38     /// The query string that was passed in to be used for the Full Text Search
   39     /// </summary>
   40     public string SearchPhrase
   41     {
   42       get { return _searchPhrase; }
   43     }
   44  
   45     /// <summary>
   46     /// The T-SQL statement to be used as the contains_search_condition parameter
   47     /// of a CONTAINSTABLE query
   48     /// </summary>
   49     public string FTSQuery
   50     {
   51       get { return _ftsQuery; }
   52     }
   53  
   54     /// <summary>
   55     /// An array of any noise words that were included in the search string
   56     /// </summary>
   57     public object[] IgnoredWords
   58     {
   59       get { return _ignoredWords.ToArray(); }
   60     }
   61  
   62     #endregion
   63  
   64     #region Private Methods
   65  
   66     /// <summary>
   67     /// Builds the Full Text Search query
   68     /// </summary>
   69     private void BuildFTSQuery()
   70     {
   71       _ftsQuery = "";
   72       string cleanQuery = _searchPhrase;
   73  
   74       // Strip out comments, wildcards
   75       cleanQuery = cleanQuery.Replace("--","");
   76       cleanQuery = cleanQuery.Replace("*","");
   77       cleanQuery = cleanQuery.Replace("%","");
   78  
   79       // Rather than simply split the string, walk
   80       // through it looking for phrases or individual
   81       // words
   82       cleanQuery = cleanQuery.Trim();
   83       while(cleanQuery.Length>0)
   84       {
   85         // If this is the only word
   86         if(cleanQuery.IndexOf('"')==-1 && cleanQuery.IndexOf(' ')==-1)
   87         {
   88           if(!CheckNoiseWord(cleanQuery))
   89           {
   90             FTSAddWord(cleanQuery);
   91           }
   92           break;
   93         }
   94  
   95         // Get the next word/phrase
   96         if(!cleanQuery.StartsWith("\""))
   97         {
   98           // Get the word from the search string
   99           int end = cleanQuery.IndexOf(" ");
  100           if(end<=0){end = cleanQuery.Length;}
  101           string theWord = cleanQuery.Substring(0,end);
  102  
  103           // Check it's not a noise word
  104           if(!CheckNoiseWord(theWord))
  105           {
  106             FTSAddWord(theWord);
  107           }
  108         
  109           // Remove the word from the search string
  110           cleanQuery = cleanQuery.Remove(0,end);
  111           cleanQuery = cleanQuery.Trim();
  112           continue;
  113         }
  114         else
  115         {
  116           // A phrase
  117           int end = cleanQuery.IndexOf('"',1) + 1;
  118           if(end<=1){end = cleanQuery.Length;}
  119           FTSAddPhrase(cleanQuery.Substring(0,end));
  120           cleanQuery = cleanQuery.Remove(0,end);
  121           cleanQuery = cleanQuery.Trim();
  122           continue;
  123         }
  124       }
  125     }
  126  
  127     /// <summary>
  128     /// Checks a string for noise words and, if any exist,
  129     /// removes them from the string and adds them to the
  130     /// array of ignored words.
  131     /// </summary>
  132     /// <param name="word">the word to check</param>
  133     /// <returns>true if the word is a noise word, otherwise false</returns>
  134     private bool CheckNoiseWord(string word)
  135     {
  136       if(IsNoiseWord(word))
  137       {
  138         _ignoredWords.Add(word);
  139         return true;
  140       }
  141       return false;
  142     }
  143  
  144     /// <summary>
  145     /// Add an individual word to the query
  146     /// </summary>
  147     /// <param name="word">the word to be added</param>
  148     private void FTSAddWord(string word)
  149     {
  150       if(_ftsQuery.Length>0)
  151       {
  152         _ftsQuery = _ftsQuery + " AND ";
  153       }
  154       _ftsQuery = _ftsQuery + "FORMSOF(INFLECTIONAL, " + word + ")";
  155     }
  156  
  157     /// <summary>
  158     /// Add a phrase to the FTS query
  159     /// </summary>
  160     /// <param name="phrase">the phrase to be added</param>
  161     private void FTSAddPhrase(string phrase)
  162     {
  163       if(_ftsQuery.Length>0)
  164       {
  165         _ftsQuery = _ftsQuery + " AND ";
  166       }
  167       _ftsQuery = _ftsQuery + phrase;
  168     }
  169  
  170     /// <summary>
  171     /// Checks if the word is a noise word
  172     /// </summary>
  173     /// <param name="word">the word to check</param>
  174     /// <returns>true if it is a noise word, otherwise false</returns>
  175     private bool IsNoiseWord(string word)
  176     {
  177       // Exclude individual characters
  178       if(word.Length>1)
  179       {
  180         // Iterate through the string array of noise words,
  181         // and check the word parameter does not match
  182         foreach(string item in _noiseWords)
  183         {
  184           if(word==item)
  185           {
  186             return true;
  187           }
  188         }
  189  
  190         return false;
  191       }
  192  
  193       return true;
  194     }
  195  
  196     #endregion
  197   }
  198 }

P.S. The code snippet above was formatted using the CopySourceAsHtml VS addin by Colin Coller.

posted @ 9:42 AM

Monday, October 25, 2004 #

New site - journalonline.co.uk

Last week a site I've been working on for a couple of months went live - www.journalonline.co.uk. Developed for the Law Society of Scotland and working with Connect Communications, the site is an online resource of information that appears in the printed magazine 'The Journal'.

The site is entirely developed in ASP.NET (using c#) and has a SQL Server 2000 backend. I made use of Paul Wilson's master pages for maintaining the site templates, and also used the Data Provider and Configuration Management application blocks. Note that if you plan to use the Configuration Management application blosk, I strongly recommend you check out the forum on the gotdotnet site where the component is hosted - there are a number of known issues with it.

The search facility provided on the site (to search the library of articles) makes use of a Full Text Index. Having used Index Server a number of times in the past to provide search facilities, I understood the ease of integration this approach would offer, and the in built facility for ranking results. It was also a low cost solution, as no third party software was required. The main downside can be the performance of the index population, but in this case that wasn't an issue as the frequency of updates was low.

The backend of the system also uses FreeTextBox (the same component used to manage this blog!).

Feel free to have a look and let me know what you think!

posted @ 12:07 PM

Thursday, October 07, 2004 #

ASP.NET security vulnerability

As everyone by now hopefully knows, there is a vulnerability in ASP.NET that could allow an attacker to bypass security and access secured content.

The fix is relatively straightforward, and there will hopefully be a proper patch from MS soon...

posted @ 10:57 AM

Thursday, September 30, 2004 #

Rant: Norton Internet Security blocks banner images

I site I've just finished developing was launched yesterday, but there were some reports that the main banner image wasn't displaying. The image was called banner.gif, and after recreating the image (to check it wasn't corrupt) and trying a jpeg version it finally turns out this was getting blocked by Norton Internet Security.

Now, this strikes me as being incredibly stupid and pointless on the part of Norton (aka Symantec). They're trying to block banner ads, yes, but by filename?!?!?! Correct me if I'm wrong, but if you had banner ads that you suddenly found out couldn't have banner in the filename, wouldn't you just rename them?

So what's the point in blocking by filename? All they achieve is potentially breaking the look of a lot of sites, as I'm sure banner isn't an uncommon thing to call the banner image for a site, and causing poor web developers a headache until they figure it out.....

posted @ 1:53 PM

Friday, September 17, 2004 #

Microsoft granted patent for tabbing through web links

Now, I can appreciate why companies want to protect their property and inventions as such, but when you can patent tabbing through web links (as reported on out-law.com), there is something well wrong with the system.

I can only hope that Microsoft don't try and enforce this, unlike the BT Hyperlink case. After all, tabbing is one of the key methods for navigating sites without using a mouse...

posted @ 5:48 PM

Wednesday, September 15, 2004 #

Page Centering using CSS

In my recent exploits using only CSS and HTML to layout a web page, I've noticed that I couldn't get a whole page to appear centrally on a page in IE5 or 5.5. This, of course, used to be dead easy when using table layouts.

Well, I've come across the solution on SimpleBits. Although I use a container DIV to centre the page in other browsers, IE5 and 5.5 needs the page text-align attribute set to center. Nice and easy!!

posted @ 3:35 PM