April 2008 - Posts

I've seen very little blogger chatter about the massive SQL injection attack that is making the news even though it is us web developers who are being blamed for it. Even Jeff Atwood has neglected to blog about it and he loves to rant about shoddy coding practices in the industry.

I suspect the silence is due to the very technical nature of SQL injection attack prevention. I've done some research on this topic and it is not as easy to fix as you might think. The best resource I've seen can be found at http://ferruh.mavituna.com/sql-injection-cheatsheet-oku/ That web page of attack vectors is huge and makes it quite clear that you cannot prevent an exploit just by parsing out a few SQL keywords.

I have inherited a classic ASP web application that is probably quite vulnerable. The original developer did not use any stored procedures and there is nothing in there to sanitize the user input. Converting all of its dynamic SQL statements into stored procedures is going to be a huge chore. First I will need to locate all the SQL statements in hundreds of ASP web pages. I do have some scripts to recursively search a directory and read target files to create such a report with line numbers. I may be able to load the web site in Visual Studio and use its search features. Then I need to create stored procedures for every SQL statement. That will probably be a few hundred. After that I'll have to write a lot of verbose VBScript code to deal with every input parameter. Here is some old sample code I have showing how much code is required for a very simple query.  

<%
Set
cmd.ActiveConnection = cn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "sp_my_query"
cmd.Parameters.Append cmd.CreateParameter("Title", adVarChar, adParamInput, 255, "Slaughterhouse Five")
cmd.Parameters.Append cmd.CreateParameter("Author", adVarChar, adParamInput, 255, "Kurt Vonnegut")
cmd.Parameters.Append cmd.CreateParameter("ID", adInteger, adParamReturnValue)
cmd.Execute
Response.Write "ID number of record inserted is: " & CStr(cmd.Parameters("ID").Value)
%>

Of course, there are going to be many bugs introduced by these changes and I'll probably have to struggle with some data types (i.e. figure out which DataTypeEnum constant to use). Last night I backed up the database for this classic ASP web application and I did not find any script blocks in its text fields but other hackers will begin to customize this exploit (which uses table cursors and system objects to discover all the table names and columns).

I have another classic ASP site and an ASP.NET site that are probably vulnerable but these are mostly non-public administration sites. I can probably delay any problems by making sure Google does not index them.

TechCrunch has reported that Live Universe has acquired Pageflakes and plans to integrate it into LiveVideo. In fact you can already get some sense of how the integration will look by visiting the beta site at http://livevideo.pageflakes.com/

This is a very interesting merger because both of these sites use ASP.NET technology. It will introduce the vlogging community to mash ups using RSS feeds and widgets. I hope LiveVideo intends to permit custom pageflakes because I would love to create some pageflakes for the vlogging community.

I've been using the LiveVideo web site for a long time because it is the second most popular vlogging site and they clearly understand vlogging's potential for social networking. In fact, I've usually included LiveVideo Featured Videos in my web parts experiments and JSON mash ups. I am well prepared to take advantage of this new social networking application platform.

Live Universe seems to be very aggressive in their attempts to dominate the social networking market. They have already expanded LiveVideo to include text blogging and social broadcasting. Most other social networking sites are completely missing the significance of vlogging to form a real sense of community and even YouTube has failed to move into social broadcasting.

I spent most of the day learning how to create a custom pageflake. This was fairly difficult because it is not well documented. I could only find three examples of sample code on the Internet, all from the Pageflakes developer documentation. The developer forum does not show much activity. I had to struggle with some advanced JavaScript (i.e. prototypes and closures). It was quite difficult to use a timer within a function prototype but I managed to create a countdown timer pageflake for a vlogger gathering I plan to attend, the YoTube gathering in Philadelphia on 07/12/2008.

According to Mashable, Live Universe may have also just wanted to acquire some top ASP.NET innovators like Pageflakes co-founder Omar Al-Zabir who blogs on http://weblogs.asp.net/.  Congratulations Omar!

Yesterday I had to use an iterator to loop through all the data values in a form request. This is well documented for classic ASP and can even be found in the old Active Server Pages SDK help file but it was difficult to find the same method to use for ASP.NET 2.0.

First I should explain why I needed to do that. I was working on another "value added service" for YouTube users which will allow them to export their video favorites to Excel. YouTube will frequently suspend or delete user accounts without warning or explanation so it is a good idea to back up your favorites or you'll be unable to find them again. Any way I had a form for entering the account username and used a PostBackUrl to transfer it to another page with its ContentType set to return an Excel file. As far as I know, you cannot change the ContentType on a postback. I was also using a master page so my form elements were getting lengthy names. I was finding it difficult to determine how to reference a form value via its name so I wanted to use the classic ASP method of looping through the form collection.

Here is some sample code on how to do this. It generates an Excel spreadsheet with the form collection key names and values:

   1: Imports System.Text
   2:  
   3: Partial Class CreateExcel
   4: Inherits System.Web.UI.Page
   5:  
   6:     Dim sbHTML As New System.Text.StringBuilder("")
   7:  
   8:     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
   9:         Response.Clear()
  10:         Response.Buffer = True
  11:         Response.ContentType = "application/vnd.ms-excel"
  12:         Response.Charset = ""
  13:         Response.AddHeader("Content-Disposition", "attachment; filename=Form Collection.xls")
  14:         Page.EnableViewState = False
  15:  
  16:         sbHTML.Append("<table border=""0"" cellpadding=""3"" style='"border-collapse: collapse"" width=""100%"" bordercolor=""#000000"" id=""table1"">" & Environment.NewLine)
  17:         sbHTML.Append("<tr>" & Environment.NewLine)
  18:         sbHTML.Append("<td bgcolor=""black"" colspan=""2""><b><font face=""Arial"" color=""white"" size=""4"">Form Collection</font></b></td>" & Environment.NewLine)
  19:         sbHTML.Append("</tr>" & Environment.NewLine)
  20:         sbHTML.Append("<tr>" & Environment.NewLine)
  21:         sbHTML.Append("<th>Name</th>" & Environment.NewLine)
  22:         sbHTML.Append("<th>Value</th>" & Environment.NewLine)
  23:         sbHTML.Append("</tr>" & Environment.NewLine)
  24:  
  25:         Dim i As Integer
  26:         For i = 0 To Request.Form.Count - 1
  27:             sbHTML.Append("<tr>" & Environment.NewLine)
  28:             sbHTML.Append("<td height=19>" & Request.Form.AllKeys(i) & "</td>" & Environment.NewLine)
  29:             sbHTML.Append("<td height=19>" & Request.Form(i) & "</td>" & Environment.NewLine)
  30:             sbHTML.Append("</tr>" & Environment.NewLine)
  31:         Next
  32:  
  33:         sbHTML.Append("</table>" & Environment.NewLine)
  34:         'Debug.WriteLine(sbHTML.ToString())
  35:         Response.Write(sbHTML.ToString())
  36:         Response.End()
  37:     End Sub
  38: End Class

I've finally used ASP.NET 2.0 on my web site. Today I uploaded an ASPX page that generates a tag cloud based on all the tags from a YouTube user's videos. I got this idea from Tweet Clouds, a web site that generates tag clouds based on Twitter posts. I searched the Internet and did not find any similar service for YouTube videos.

There were several challenges in this project. The first problem is that Google gData will only return 25 results at a time. Therefore I had to make an initial request just to determine how many videos I need to get. Then I had to remove nodes from that XML response and make several more requests to add 25 XML nodes at a time until I had a complete XML document. Below is the code snippet I used for that particular difficulty.

   1: Dim objXmlNode As XmlNode
   2: For Each objXmlNode In objEntryNodeList
   3:         objXmlDocument.DocumentElement.AppendChild(objXmlDocument.ImportNode(objXmlNode, True))
   4: Next

Technically I did not need that XML document since I'm only interested in the media keywords but I was able to save the XML as a file for debugging purposes.

After that there was the programming challenge of getting a count of each unique word. Fortunately life is an open book test. I did some research on the Internet and found that using a hash table would be the best way to handle this problem. I didn't find exactly the code I needed but I managed to figure out how to use a hash table. Below is a code snippet:

   1: ' use a hashtable to get unique word counts
   2: Dim strWord As String
   3: For Each strWord In objKeywords
   4:     If objHashTable.Contains(strWord) Then
   5:         ' word already in hash table, increase its count
   6:         Dim intCount As Integer = objHashTable(strWord)
   7:         intCount = intCount + 1
   8:         objHashTable(strWord) = intCount
   9:     Else
  10:         ' word not in hash table yet so add it
  11:         objHashTable.Add(strWord, 1)
  12:     End If
  13: Next

As for the actual tag cloud, I used a control that was published on http://www.codeproject.com/KB/aspnet/cloud.aspx. I did have to make a slight adjustment to its code to get a space in the generated HTML code. I could not get the tag cloud to word wrap without that space.

Another thing I learned on this project was how to add meta tags to a content page which uses a master page. According to many Search Engine Optimization experts, meta tags are not very important anymore but I at least wanted a description tag. The following code accomplishes that:

   1: Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
   2:     ' create meta tags
   3:     Dim metaTagDesc As New HtmlMeta
   4:     metaTagDesc.Name = "description"
   5:     metaTagDesc.Content = "A web application that generates a tag cloud based on all the tags used in a YouTube user's videos."
   6:     Page.Header.Controls.Add(metaTagDesc)
   7:     Dim metaTagKeywords As New HtmlMeta
   8:     metaTagKeywords.Name = "keywords"
   9:     metaTagKeywords.Content = "YouCloud,YouTube Tag Cloud,Video Tag Cloud,YouTube Tags,YouTube Cloud,YouTube Video Cloud"
  10:     Page.Header.Controls.Add(metaTagKeywords)
  11:     ' add JavaScript events to web controls
  12:     If Page.IsPostBack = False Then
  13:         btnSubmit.Attributes.Add("onclick", "loading();")
  14:     End If
  15: End Sub

After completing this project I thought about how to make it all worth my while. The Tweet Clouds site has a Pay Pal donation button but that uses a form which did not work within my ASP.NET master page form. Pay Pal donation buttons have a bad reputation among YouTube vloggers because some users make e-begging videos asking for donations. That has created a lot of drama.

I thought it would be better to use Google AdSense. I checked my Google AdSense total earnings for all time and found I've made $6.37 in three years! Oh my, I better not spend all that in one place. Still it is better than the 89 cents in dividends I make from my two shares of Microsoft stock. Besides the text ads there was also the option of using a "video unit" which was more appropriate because it uses YouTube Partner videos. I created a video player featuring the videos of NutCheese, a vlogger who runs a Stickam webchat room that I spend 5 hours a night in. If she makes a fortune from my video unit then I'll hear about it.

You can generate a tag cloud for any YouTube user at: http://www.williamsportwebdeveloper.com/YouCloud.aspx

I've thought about changing this into a web service that returns the HTML for the tag cloud but I don't see how that would benefit me.

Today I spent the morning trying to figure out some of the reasons for my aggravation with Silverlight development. The first thing I discovered was that I had the RC (Release Candidate) version of the Silverlight 1.0 SDK instead of the RTW (Release To Web) version. This can certainly lead to many aggravating errors and problems.

The only way to tell the difference between these two versions is to look at some timestamps. The Release Candidate version has Timestamp July 26, 2007. The RTW (Release To Web) version has Timestamp November 15, 2007.

Similarly, the Silverlight.chm RC help file is dated 7/26/2007 while the Silverlight.chm RTW is dated 10/29/2007. The Visual Studio 2005 template will refuse to update because it is already installed so you'll need to manually copy the SilverlightJSApplication.zip file into the C:\Documents and Settings\[username]\My Documents\Visual Studio 2005\Templates\ProjectTemplates\Visual C#\Silverlight folder. Note the difference in file size and modified date.

The next thing I looked into is the XAML namespaces which give me a lot of problems. The xmlns="http://schemas.microsoft.com/client/2007" namespace causes errors in the Visual Studio 2005 XAML Designer and XamlPad. I always have to change this to xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" before I can see how my XAML will render. I've decided that this must be by design. The "client" in the Silverlight XAML namespace must refer to the browser client and is not valid when using a WPF tool. However this is pretty aggravating because it makes it difficult to preview the user interface.

Then I downloaded the Silverlight 2 Beta 1 SDK which includes Silverlight help collections that integrate into the Microsoft Document Explorer. This includes both the Silverlight 1.0 and Silverlight 2.0 Beta documentation but you have to manually register them by following the intructions in the readme file.

The Silverlight "HyperlinkButton" control is designed for Silverlight 2.0, not Silverlight 1.0 so that does not help me create hyperlinks. I think my next step is to investigate Visual Studio 2008 and Silverlight 2.0.

Today I worked on a Twitter client in Silverlight. I got pretty far on this project but had some problems creating hyperlinks in the text. I tried the Hyperlink tag in the XAML Pad and it worked there but it would not work in my Silverlight project. I did some research on the Internet and found a web page with a hyperlink example. Incredibly, this example would have you handle all the mouse events and even the text decoration to make a TextBlock act like a hyperlink. This web page also directs you to "See the documentation for TextDecorations property of the TextBlock object in the Silverlight SDK".

http://www.silverlight.net/quickstarts/silverlight10/controls.aspx

So I check out that help topic in the Silverlight SDK and find the example for "Simulating a Hyperlink using the TextDecorations Property". WTF!! I could not believe this. You mean the technology that is supposed to revolutionize the Internet with rich client web applications can't even create a simple hyperlink? I have to go to this much trouble just to simulate a hyperlink? Unbelievable!

Well...I was going to put what I managed to get working on my web site, without hyperlinks, but I cannot open the project in Visual Studio 2005. I could open the project at work but not at home. When I try to open the web page without using Visual Studio I just get a lot of errors.

OK I've managed to deploy it on my web site but don't be surprised if it throws up some errors:

http://www.williamsportwebdeveloper.com/Silverlight-Twitter.html

Silverlight is definitely proving to be far more trouble than it is worth.

More Posts