Tuesday, 28 April 2009

Today's Learning Points - AutoCompleteType & RegisterStartupScript

Just wanted to share a couple of things I discovered in ASP.NET today.

We had some security testing done on our main web app a few months ago, as a result of which we did work around things like password expiry, complexity etc. We got retested last week and we've been asked to review three points, which I've been looking at today.
One of the points was that on our login page, our password textbox is auto-completable. So I edited the page today to add "autocomplete='off'", however as I started typing Intellisense kicked in and revealed to me the AutoCompleteType attribute. I'd never seen this before! There's a whole Enum of options you can use for autocompletion, or if you set AutoCompleteType="None" then input elements that share a common ID will share their values for autocompletion.
To output "autocomplete='off'" the ASP.NET markup is

However when I was checking the output in View Source, the autocomplete attribute wasn't being rendered at all, presumably because, duh, it opens a security hole. So how did our testers pick up on this? We suspect they'd used the 'Do you want to remember this password' feature, which we don't believe we can defend against.

I dropped some project work onto our internal test site last week, where I've done some enhancements and also moved the project up to ASP.NET 3.5 and added a couple of UpdatePanels with some controls from the AjaxControlToolkit. I had an email today from our user who is doing some testing, who said that some of the buttons didn't seem to do anything eny more. I ran the project upon my laptop, checked it and found I was seeing the same behaviour. I dug into the code and reminded myself that the buttons that weren't working, worked by emitting some script using ClientScriptManager.RegisterStartupScript.
Knowing that the major change to the page was to add UpdatePanels, it didn't take much to deduce that a combination of UpdatePanels and partial page rendering had broken the RegisterStartupScript model. But how to solve it? My first thought was to change the ScriptManager's rendering mode to disable partial page rendering on the basis that if you re-render the entire page then a startup script might be correctly emitted, however on trying this I learned you can't change the rendering mode in any event that occurs after Page_Init. But I did spot that there are several other methods on ScriptManager, including one called RegisterStartupScript. I swapped out my calls from ClientScript.RegisterStartupScript to ScriptManager.RegisterStartupScript, ran it up, and success, my buttons were functional once more. And I should go on to learn the other methods of ScriptManager...

No comments: