February 2007 - Posts

ASP.NET Black Belt Training :: April 21st, 2007 :: San Diego, CA
28 February 07 09:07 PM | Scott Mitchell

On Saturday, April 21st I will be putting on a one-day event covering many real-world tips, tricks, and techniques for building data-driven ASP.NET 2.0 web applications. Starting from scratch, we'll build a feature-rich blog engine application that showcases a number of best practices and common challenges, including: building a layered application architecture; implementing a system to log unhandled exceptions; using caching to boost performance; efficiently paging through large amounts of data; implementing dynamic URL rewriting via an HTTP Module; making a site's appearance customizable through the use of dynamic themes and skins; and many more topics (see the outline for a more detailed look at the day's syllabus).

This event is taking place in San Diego, California and runs from 9:00 AM to 5:00 PM with lunch provided. Specifically, the event will be held at the UCSD Extension building in Sorrento Mesa [Directions].

The cost for this event is normally $299, but if you sign up by March 21st the rate is discounted to $199.

For more information about this event, see the ASP.NET Black Belt Training homepage. Sign up at http://fuzzylogicinc.net/BlackBelt/SignUp.aspx.

There is only room for 48 attendees. The last time this event was offerred, it sold out in two weeks...

Hope to see you there!

Filed under:
Four New "Working with Data in ASP.NET 2.0" Tutorials Now Available
21 February 07 09:02 AM | Scott Mitchell

My Working with Data in ASP.NET 2.0 tutorials have been updated to include the four newest tutorials, which illustrate working with database data directly from an ASP.NET web page. The previous 46 tutorials (as well as all tutorials following these four) looked at working with data through a layered architecture. But for one-off projects or prototyping, it may be preferable to use a SqlDataSource and avoid building the architecture. These four new tutorials illustrate various facets of working with the SqlDataSource control:

  • Querying Data with the SqlDataSource Control [VB | C#]
  • Using Parameterized Queries with the SqlDataSource [VB | C#]
  • Inserting, Updating, and Deleting Data with the SqlDataSource [VB | C#]
  • Implementing Optimistic Concurrency with the SqlDataSource [VB | C#]

Like the previous tutorials in the series, all tutorials are available in C# and VB, include the complete code download as a self-extracting ZIP, and are available in PDF format. Also, the layout of the tutorial homepage has been revamped and a new style has been applied for the individual tutorials.

There are more tutorials to be released in the upcoming weeks, including tutorials on working with binary data (images, PDFs, etc.), caching, and much more!

I've Noticed My CAPTCHAs Effectiveness is Decreasing
20 February 07 05:05 PM | Scott Mitchell

About six months ago I implemented CAPTCHAs here on ScottOnWriting.NET and immediately saw comment spams drop from dozens a day to virtually zero. Sure, I occassionally found a comment spam or two every week, but the tide of spams had been abated. That's not the case anymore. I know get about 5-10 comment spams per day now.

I take it this uptike in comment spams despite the CAPTCHA means one of two things:

  • There's some security hole in my blog comment system where spammers can post comments without needing to use the CAPTCHA, or
  • Brute force is in effect here. There are folks out there who are taking the time to type in the CAPTCHA to propagate their spam.

I'm inclined to believe the latter explanation is what's happening because if there were a hole I'd expect to comment spam to ratchet back up to its previous, pre-CAPTCHA level. Assuming that spammers are taking the time to enter the CAPTCHA, it makes an interesting (albeit somewhat depressing) economic commentary: either that spam pays well enough to justify this behavior or it doesn't pay that well, but the people recruited to continue this spamming are “selling” their time for so little that the actions are still profitable. It's a bit of both, I'm sure, but it's sad because I would wager these people taking the time to surf to sites, paste in their spam, and enter the CAPTCHA, could be benefiting humanity moreso by producing a good or service.

The only real guard against comment spam is moderation or simply turning off comments. I've actually taken the latter approach with some of my other blogs because the hassle of periodically removing the comment spam or proactively moderating outweighed the value the contributors' comments.

Filed under:
March's Toolbox Column Now Available Online
15 February 07 01:15 PM | Scott Mitchell

My 15th Toolbox column in the March 2007 issue of MSDN Magazine is now avaiable online. The March issue examines three products:

  • GoToMeeting - a desktop-sharing meeting tool that supports meetings of up to 10 participants. Very useful for telecommuniting or consulting on remote projects.
  • SlickEdit - a lightweight code editor that offers many of the essential features, but without the bloat that's present in Visual Studio.
  • FlowChart.NET - a component for displaying and modifying flowcharts, diagrams, hierarchies, and a myriad of other types of classification graphs.

This month's issue reviewed Accelerated C#, by Trey Nash.

As always, if you have any suggestions for products or books to review for the Toolbox column, please send them into toolsmm@microsoft.com.

Filed under:
Opening a PDF in a Popup Window In Internet Explorer
02 February 07 06:17 PM | Scott Mitchell

Today I was working on a web application where we have a number of Crystal Reports. To date, we were displaying them using the CrystalReportViewer Web control, but virtually all users, we found, were using the reports in the same manner:

  1. Click on the link to view the report in the CrystalReportViewer in a popup window
  2. Click on the print icon
  3. Specify the pages to print. This refreshes the web page and shows it as a PDF
  4. Click the print button on the PDF document in the browser

(Side note: Will there ever be a paperless office? Not in the health care industry, that's for sure!)

To streamline this process we decided to have the CR render as a PDF automatically. The code is pretty straightforward, and we ended up using code very similar to that presented in Use ASP.NET to Launch a Report as a PDF. Once this code was implemented, clicking a link would display a popup containing the report in PDF format... in FireFox.

In Internet Explorer 6, the popup window was empty. Using Fiddler, I could see that the PDF data was getting sent down, that the Content-Type MIME header was kosher, and so forth. A little Googling revealed that IE is a little fickle about displaying PDFs in popups. The workaround we ended up using - courtesy of Cowboy Bob's answer in the Unable to Display a PDF in IE When Within a Popup Window message post - was to “trick” IE by ending the URL with “.pdf”.

That is, in the window.open JavaScript call we previously had something like:

window.open('ShowCR.aspx?doc=1234', ...);

And to get this to work in IE we had to change this to:

window.open('ShowCR.aspx?doc=1234&iefix=fix.pdf', ...);

Basically, IE had to see “.pdf” at the end of the URL to display the PDF in the popup window. Bleh. Is this fixed in IE 7? I sure hope so.

(I also added a few lines of code to the Page_Load event handler in ShowCR.aspx so that if the querystring didn't end with “fix.pdf”, the page would Response.Redirect back to itself appending “&iefix=fix.pdf” to the URL. This way, if a previous or future link forgets or doesn't have the appropriate ending for this IE hack, it will automatically get tacked on and the report will properly display for our IE users, which is like 99% of the user base.)

A Potential Security Hole with "Remember Me Next Time"
01 February 07 12:13 PM | Scott Mitchell

When a user authenticates in ASP.NET using forms authentication, the forms authentication system writes an authentication ticket to the user's cookies that allows the site to remember that the user has already been authenticated. This authentication ticket either lasts for the duration of the user's visit, for a specified duration, or can be persisted on the user's machine. If a timeout is specified, it can be a sliding or absolute duration. To specify this duration, from Web.config use the <forms> element's timeout and slidingExpiration attributes. It's a little confusing because the rules governing the cookie expiry changed between ASP.NET 1.x and 2.0.

In ASP.NET 1.x, the timeout settings are ignored for persistent cookies. For ASP.NET 2.0, the timeout settings only apply to the persistent cookies. Moreover, in ASP.NET 1.x the expiry defaults to be sliding, while in ASP.NET 2.0 it defaults to be absolute.

What this means, in English, is that in ASP.NET 1.x if you created a non-persistent authentication ticket cookie, it would last for the specified timeout (default is 30 minutes) with the timeout automatically being refreshed each time the user visited a new page in the site. In short, if a user visited a site, logged on (but did not choose to have their credentials remembered for subsequent visits), the cookie would be good until the user let 30 minutes (or whatever) lapse between visiting the site. If the user logged on with a persistent cookie, the cookie would have a duration of 50 years! Crazy. This, as we'll discuss shortly, carries with it some security concerns.

ASP.NET 2.0 takes a much more conservative approach toward authentication ticket cookie expiries. For non-persistent cookies, the cookie lasts for the duration that the browser's open. There's no timeout, but once the browser closes, the user will need to re-authenticate when the next visit the site. Persistent cookies have an expiry based on the timeout value (again, a default of 30) and it defaults to an absolute timeout, meaning that after 30 minutes, regardless of how often they hit the site, the user will have to reauthenticate. This settings, of course, can be changed through the <forms> element as noted above.

The authentication ticket is persisted on the user's machine across browser restarts (but only for the specified timeout duration) in ASP.NET 2.0 if the Login control's “Remember me next time” checkbox is checked. One potential security hole here is introduced because of the disconnect between authentication and the user's underlying information in the Membership system (or in some custom user store system). Consider the following scenario:

  • User A logs into site and checks “Remember me next time“. Imagine that the site has a timeout of three days.
  • User A then posts messages to the forum on this site and blasts a lot of spam and other garbage
  • Mr. Administrator sets User A's IsApproved value to False. If the user goes to Login.aspx, they won't be able to validate their credentials, but............
  • User A has a persistent authentication ticket cookie on his machine that is good for three days. So if User A visits tomorrow, he's still able to pass the authorization checks. If there's no additional logic on making posts that ensures the poster is approved, blam, User A is back to making his garbage posts.

Any suggestions/recommendations on preventing this? I see two options:

  1. The application should not allow posts from unapproved users. Such a check could be done right before the post is committed to the database, for instance. This would prevent an unapproved user from making a post, but would still let them get on the site via the persistent authentication ticket cookie (until it expired after three days).
  2. Use a Session variable to indicate if a user has had their Approved status validated. If so, do nothing. If not, then check Membership.GetUser().IsApproved to make sure it has a value of True. If it does, set the Session variable to indicate that the check has been performed. In a base page class, override OnInit and perform this logic. Then have all ASP.NET pages in sections where only authenticated users are allowed derive from this base page class so that all pages make sure that the users visiting the site are approved.

Any other suggestions or workarounds for this issue? Granted, one could simply shorten the persistent cookie timeout, but that kind of defeats the utility of “Remember me next time.” The good news is that because ASP.NET 2.0 is much more conservative than ASP.NET 1.x by default, the window with which an unapproved user has to access the site is greatly reduced.

Filed under:
More Posts


My Books

  • Teach Yourself ASP.NET 4 in 24 Hours
  • Teach Yourself ASP.NET 3.5 in 24 Hours
  • Teach Yourself ASP.NET 2.0 in 24 Hours
  • ASP.NET Data Web Controls Kick Start
  • ASP.NET: Tips, Tutorials, and Code
  • Designing Active Server Pages
  • Teach Yourself Active Server Pages 3.0 in 21 Days

I am a Microsoft MVP for ASP.NET.

I am an ASPInsider.