ASP.NET: Don’t do that... do this!
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Edwards, Damian
ASP.NET’s been around for a number of years and the team’s developed some DOs and DON’Ts. Let’s explore out very best list of DON’Ts that you can apply today at work! Come see Damian Edwards, Senior Program Manager on the ASP.NET team, share internals, secrets and not-so-secrets of the ASP.NET APIs that you should be exploiting and the ones you should be avoiding.
 I'm just waiting for my machine to boot up. I just finished another talk and my machine decided to have a bit of a rest in between as I walked over here. So I'm trying to get it started up again. We're going to talk about some interesting stuff today. I've given this talk a couple of times already. It's really designed around, well, I'm probably going to hurt some people's feelings in this talk. This is advice from the ASP.NET team based on things that we've seen people do in the wild. Given that ASP.NET is a fairly old framework now, it's over 10 years old. There's a fair bit of legacy. There's some security things that are interesting to talk about that have been fixed along the way, but some people may not know about them and are doing things incorrectly. There are some APIs that we wish that we'd never invented or they serve their purpose and now we don't want you to use them anymore. So I'm going to tell you about those. For every one of the ones I tell you not to do, I will give you an alternative of what you should do instead. As I said, I'm pretty much guaranteed to offend at least one person in this room, with what I'm about to tell people not to do. If I'm really good, I'll freak someone out enough that they call back to work and ask them to pull down their website immediately because they're doing something that's completely insecure. We'll get there. Come on, come on, laptop. Who was in my last session with David? There is no coding in this session. This is all me talking about APIs and what not to use and what to do. There is a PowerPoint and I link off to some examples and things. There is no coding in this demo. I'm coded out today. Come on, come on, come on, come on. How many people here have been using ASP.NET for two years or more? Okay, three years or more. Keep your hand up. Four years or more? Five years or more? Six years or more? Seven years or more? Look at the stayers. Eight years or more? Now dropping off now, nine years or more? What are we back to? That's out of 2004? Ten years or more? Eleven years or more? Came out in 2002, by the way. This is where it stops unless you use the beta. Twelve years or more? Thirteen years or more? First beta? Who used ASP Classic? Okay, a lot of people. Okay, here we go. It's up. That filled in the time beautifully. Plug this in. No God's willing. This will just work this time. I want that one. And just for good measure, I'm going to paste it out to the desktop. Oh, come on. Come on. There we go. I was tricking you. No, do not start in safe mode. Just start. There we go. All right. The last time I gave this talk, there were a lot of Scots on stage. Scott Hack, the little-known Scott Hack. This time it's just me. All right. ASP.net, don't do that. Please do this instead. Really obligatory disclaimer written by the security guy on our team that we never question about anything he says about security. This is not intended to be like the complete guide where if you follow everything in this guide, in this presentation, then that's it. You're golden and we're signing off on your application. Ship it. You're never going to have any problems. This is not that, of course. This is stuff that we would like to bring to your attention based on previous guidance that we've given you and perhaps we're changing our guidance. We only intended to call out the most common, incorrect, or undesirable uses that we encounter when we look at people's applications. People file bugs. They send up repro's and we go, oh, you're doing that. Please don't do that. This is a collection of those things. We've broken the talk into sections. The first one is around standards compliance. We're talking about HTML standards compliance. JavaScript says that type of thing first. Control adapters. Whoever used control adapters in web forms. There's a lot of web form stuff in here, believe it or not. Yes, control adapters. Control adapters were originally designed to support mobile controls. We had this fantastic feature in ASP.net 2 about mobile controls. You drag a text box, a mobile text box, onto the page and it would render different HTML or WML or XHML or XML depending on what the device was. It did that using our browser capability system and these things called control adapters. The one control could adaptively, in a pluggable fashion, change what it renders at run time. We don't want to support it anymore, so please don't use it. It's an old technology. We deprecated the mobile controls themselves, but a lot of people are still using control adapters. We would prefer that you do this using CSS, render standards compliant HTML, either using a control that you wrote or one of the ones in the box or just basic HTML. Then you use CSS, media, queries, responsive design, all that good stuff to do the mobile specific logic in your application. Who is doing the stuff on the right today? Responsive design, media, queries, great. Perfect. Who has ever used the stuff on the left to do mobile websites? Anyone? Okay, good. It served its purpose. Before we had CSS, there was a time, it was, or devices that didn't support CSS, you had to do this. Now we just sort of assume that everyone has a smartphone or at least a phone with a browser that supports some level of HTML, CSS, so don't use them anymore if you can avoid it. Okay, style properties on controls. This is code behind textbox.style.editititem template, alternate item font, four color opacity level. There are hundreds and hundreds of these properties on the web forms controls, and I hate them. You're in your markup and you're doing grid view, colon, blah, blah, blah, and then you hit E and you get a list of intelligence with 100 items in it that's just full of this garbage. Okay? You shouldn't be setting your CSS in line on your HTML anyway. We all know that. You should be attaching it via CSS. Now I would love to, in a future version of ASP.net and web forms, literally delete all of these properties. Just get rid of the style collection class and get rid of the styles property and force people to use CSS to do it the right way, quote, unquote. So please, if you are using this today, very common if you're doing things like data binding, you're handling the on item data bound event, and then you go in and you navigate through the cells, look at the value. If it's less than zero, then you say, oh, current cell.style.fourcolor equals color.red. Okay? Don't do that. Do current cell.CSS class equals string negative. Then add a CSS style sheet with a class called negative, has a semantic name, and set the four color of the font that way. Much more maintainable. You don't have colors and all types of style crap embedded in your C sharp. We will be able to clean up this intelligence in the future for you as a result. Please don't use style properties. Page and control callbacks. It's introduced in.NET 2. This is the thing that lets the grid view do paging and sorting without having to do a full page request. This is not update panels. That was different. Anyone used page or control callbacks? Okay. Also known as page methods. You could have a static method on your page, and then you could invoke it using Ajax. Okay? Kind of nice. Ish. Just don't use them. We have better ways of doing this now. These cause some issues with some of the newer stuff. Friendly URLs, the stuff we added in web forms this year that gives you the extensionless URLs for web forms, doesn't work well with this. Routing does not work well with this. If you want the modern URLs, the ability to control your URLs using routes, then have them separate to your pages and your controls and whatnot. It doesn't work well with page callbacks and controls with callbacks. Just use anything else. Anything but that. Okay? Update panel is fine. Update panel is an amazing piece of technology. It really is. I've seen the patent. Okay? It's patented. It's really cool. Just don't abuse it. Okay? Know how it works. Understand what's going on, and then use it for the portion of the page that you want to use it for, and just be mindful of it, and test it, you know, to perform this test and whatnot. Just use Ajax MVC action methods, web API, signal R, whatever it is you want to do to get that Ajax-y type non-full page refresh back, but try and avoid page and control callbacks. If you're using the grid view or a control that itself uses control callbacks, just turn that feature off or don't enable it in the first place. None of the controls will use it by default. You have to turn it on in order for it to work. So just don't turn it on. Okay? Capability detection. So we have this feature in ASP.NET called BrowserCaps or Browser Capabilities, which is this massive XML database that's installed on the server that says, hey, this browser with this user agent string is IE whatever or Firefox whatever, and it supports ActiveX, Cookies, this type of image format. It has this wider screen, blah, blah, blah, blah, blah, blah. Okay? And there are third party vendors who sell expanded versions of these databases for mobile devices and things. And people have used this for a long time, the mobile controls that I talked about before, they use this. But we generally now know that doing browser detection or capability detection from a static reference is generally frowned upon. Okay? We don't like doing that anymore. We don't use the agent sniffing. We don't test for one thing and then assume that something else will be there because that thing was there. We know that's bad, right? So we should be doing feature detection. So we should be lighting up our features in the client where we can test for those features in real time using JavaScript or clever CSS tricks. Oh, I know that this browser supports ping images because I tried to write some code that should result in this element appearing and it didn't. Or now I know it didn't support ping images, but you get the idea. So we have tools like Modernizer, great library from a couple of guys, Guy at Google, a guy to a few other guys, Paul Irish, a couple other guys. We ship it in our templates. There's a client-side library that helps you determine what are the capabilities of the current browser, but it does it using feature detection, not via some big static list of features that it understands. Okay? So please use feature detection and not capability detection. Okay, so that's everything about standards compliance. I'll stop ranting about that now. And we'll talk about security. This is where it gets a bit scary. Okay, so request validation. Who knows what request validation is in ASP.net? Okay, is that really annoying thing that gets in the way when you try and post back anything that looks like HTML? Yes, you turn it off, which is what most people end up doing, which is bad because it means that we probably didn't design the feature very well. So the idea behind request validation was that, hey, let's not have the developer have to worry about cleansing all the input coming in from the browser on the odd chance that they may echo that input back out to the browser, or they may inject that input into a SQL string. Okay? We'll detect, detect any malicious type of content. Oh, there's an angle bracket. Oh, there's a question mark after or whatever. Shut down the request before your handler even gets assigned. So it's a module that runs really, really early in the HTTP pipeline in ASP.net. It inspects the request. So it looks at the form body. It looks at the query string, and it looks at the request path. And it sees anything it doesn't like. It just kills the request on the spot. You get that yellow screen of death, hey, a potentially dangerous token was found and blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, and you go, ah, damn it, you turned it off. You never use it again. Now, we did add features in version 4.0 that let you do it more granularly. So in MVC, for instance, you could say, I just want this text box in MVC to not go through request validation, but let the rest of the page go through request validation. That was nice. You could turn it on for the whole page, but just not have it on for this control. And I'm sorry to say we actually did the work in ASP.net 4.5 to support that same thing in web forms. And then we decided that we didn't want people to use it anymore after we did all the work. So we do not want you to depend on request validation. And there's a reason. It's because request validation is a game of whack-a-mole. We find or we get reported a vulnerability where browser foo version X doesn't like it if you send in a request with a form body with this seven-character string escaped with Unicode 7 or something crazy. That gets through request validation. So now we have to patch request validation, send it out to the world. That's a really expensive effort. And we just can't win because this stuff changes all the time. There are new browsers every week, new versions that introduce new vulnerabilities, and we can't keep request validation up to date. And anyway, it's a bad idea. It actually encourages bad practice. We're giving you a crutch that you shouldn't be relying on. So what should you do instead? Who knows what you should be doing instead? Come on, I have nothing to give you, but I'll be impressed if someone can give me the answer. What's the answer? No one knows. So encoding is one, half of it. Well done, sir. You need to encode your output, whether it's going into SQL via a parameter or going into the HTML via HTML encoding, and you need to validate your input. If you're expecting a URL from as the input from some text box that the user is typed into, validate it as a URL. Don't use Regex for God's sake. Don't use Regex. We have types in.NET. One of the nice things about.NET is this big library of useful features. And then we have a type, like system.uri, which you can pass the string into. And it will tell you whether it's valid HTTP, sorry, a valid URL or not. And it is written to the spec. So if it says it's a URL, it's a new URL. If it says it isn't, it isn't. You don't have to do that. So validate the input on the way in. If it should be a number, make sure it's a number. If it should be a string without certain characters, write a parser. Maybe you could use Regex in that case. If it should be an email, what's the best way to validate email? Send an email to the address and wait for a reply. I am not kidding. It is the best way and really the only way you will ever truly guarantee that the email address that someone has written in is a valid email. It may look like a valid email, but it's not valid unless they can get an email on it. And if you've read the email spec, including supporting international characters in your email, which all modern clients do, modern mail servers do, I can type an email address that contains a domain which contains a Unicode extended character pairs. Chinese, Kanji, and hieroglyphics and all types of windings, whatever I want. Emoji characters. I can have an email totally made of emoji. Does your Regex support emoji email? I pretty much guarantee not. So all you should really do is go, it's an email. I know it has to have an at sign in there somewhere and it can't be the first character and it can't be the last character. So check for that. That's fine. Although technically you could escape the at sign. So anyway, you could do that and then once you get the string, send an email to it. And then just say to them, hey, we got your email address. That's great. Sometime in the future you'll get an email. Please reply to it and then we'll activate your account, whatever it is that you're doing with that email. And then on the way out, always encode your data. So if you're in Razer, good news. It does it for you by default. You just do at foo where foo is some variable, a string or an int or some user provided data, something you got from a database that your business users might have had access to. You need to protect against that as well. Then just do at foo. It'll automatically HTML encode it for you. There is no way they can get bad data into the page. That sort of result in a cross-site scripting vulnerability in your page. If using ASPX in version four of.NET, we introduced angle bracket percent or bumblebee as we call it, colon. So angle bracket percent equals should never, ever, ever, ever, ever be used anymore. Just don't use it. You can't do it in Razer. There's no way to say don't encode it. The way you say don't encode it is to give it a variable of type IHTML string. Then it will go, oh, it's HTML already. I don't need to encode it. You have explicitly stated that this is not a string. It's an HTML string. So don't use and colon supports the same thing. Just don't use equals anywhere. Who currently knows that they have angle bracket percent equals in their site? It's the first thing you're going to do when you get back. Seriously. And if you're using data binding in web forms and you're using angle bracket percent pound or hash and then like bind or eval, in.NET 4.5, we added hash colon, which does the same thing. It performs a data binding expression, gets the value, and then encodes it automatically for you. If you're not using.NET 4.5, I'm sorry, you'll have to manually call HTML, you know, HTML with a servi utility dot HTML dot HTML encode and then pass in the result of the binding expression. If you're using two-way data binding, the bind angle bracket percent colon, angle bracket percent hash bind, who's using that? Anyone using that in web forms? Okay. There is no way to encode that unless you're in.NET 4.5. So upgrade to.NET 4.5 and change that to hash colon bind, then you're safe. Okay. Excellent. Ah, yes, because that's required for.NET 4.5. It is. Yes. You have to actually encode the values that you're binding to. So the thing you're binding to has to already have been encoded. Okay? That's the way you'd have to do it. And don't forget about JavaScript. If you're emitting stuff from server code into a script block or into a CSS attribute into style equals, you have to do different encoding. They're different languages. You can't HTML encode in there. And we have methods for those. JavaScript string encodes, CSS encode, URL encode. If you're emitting a string into an href attribute, that's not HTML anymore. It's a URL. Again, you have to correctly encode the value to ensure that people aren't trying to pass values in through a URL. Which people do. It's how you get cross-site scripting in your site. It's a really, really nasty bug to have. All right. Cookulous, FormsAuth, and Session. Another brilliant feature of ASP.NET since 1.0, who's using, who knows what Cookulous, FormsAuth, and Session is? Okay. Who's using it? Great. I'm doing everything. Who has used it in the past? Anyone? Okay. Good. So in the end, basically, it was designed in the early days when a lot of browsers didn't support cookies. We cared about browsers that didn't support cookies. And we wanted to use FormsAuth and Session. But you know what? It just don't use it. It's insecure. Okay? You should never be passing around this stuff in the URL, which is what Cookulous does. It depends on the URL. It's just a really, really bad idea. So enable require cookies for these features. There's actually a flag that says require cookies. Okay? So you can turn that on to ensure that you'll never accidentally support a browser that turns up with cookies turned off. And then you'll start passing around tokens that are potential security vulnerability. And consider using only SSL cookies for sites serving sense of information. So that means if you're writing a cookie or using FormsAuth, then if that cookie contains sensitive info, like a authentication ticket, you should only be sending it over SSL. And the cookie should be marked as only being able to be sent over SSL. There's actually a secure flag on a cookie, and the browser will not send it unless it's an HTTPS connection. And that's all configurable in ASP.net. Whether you create the cookie yourself in code behind, there's a flag on the cookie, is secure, set it to true. Or if you're using FormsAuth or Session, you can set that flag as well in the configuration. Enable ViewStateMac. Oh boy, this one's a good one. Who knows what this is? Enable ViewStateMac. Everyone knows what ViewState is, right? The thing we love to hate? So ViewStateMac is the thing that ensures that the ViewState that was posted when you do a Form post is valid. It ensures that the ViewState came from the server originally. Because if you think about what's in ViewState, what's in ViewState? It's state to do with the controls that were rendered, or it's stuff that you put in there manually. And whatever is in that state affects what the controls do. It may rehydrate a bunch of properties that you would set after page load, or it may trigger an event and then call into your code. So you really want to make sure that when someone does a post to your website to an ASPX page, that the ViewState payload that comes up, which is a base 64 bunch of characters, we undecode it and then basically we deserialize it into binary types and then we run code. You should already be worried at this point. You need to make sure that that's a valid piece of ViewState that only came from your server. You need to ensure that it hasn't been tampered with. Someone hasn't tried to manipulate the ViewState in such a way that they can make your code do something you didn't want it to do. So do not ever, ever, ever turn this off. We should never have let you turn this off. Has anyone here ever turned this off? This is a setting in the page or in web.config. Enable ViewStateMac equals false. Has anyone ever done it? Has anyone ever admitted to doing it now that I've said that? But I'm not using ViewState as not a valid excuse. Unfortunately, we called the property enableViewStateMac, but then we used it to enable other things that don't do with ViewState, like ControlState and event validation and all the other things that web form sticks in hidden variables and then uses to sort of rebuild the page when you post back. It's incredibly important that you never, ever turn this off and in a future version of.NET, we will remove the support for this. If you set this to false, we'll just blow your application up. It is incredibly dangerous. There's actually unpublished vulnerabilities about this thing. Yeah, so just tease us forever, allowing it. So here is a public vulnerability. I get the hyperlink. Where's the hyperlink? Ah, give me the hyperlink. It's, you know what? I'll format it as a hyperlink. Seriously, PowerPoint, that was a hyperlink. Last time I did this. There is actually a public known vulnerability. If you turn this off, which it is not by default, of course, it is on by default, meaning it's secure. But if you turn it off in your app, there are publicly reported vulnerabilities that you could be susceptible to that will enable cross-site scripting in your app. It means I can make a malicious request to a page where this is turned off. I can manipulate the view state because it's not encrypted and it's not verified. It's not signed with a Mac, HMac. And then I can tell your site to do something that you didn't intend it to do. Get it to render stuff into a page for another user that makes it run my JavaScript, for instance, really, really bad stuff. Medium trust. Who uses medium trust in ASP.NET? Really, everyone's running full trust? Really? Who doesn't know what medium trust is? So,.NET supports a partial trust system. The idea of having your application code run inside an app domain that is restricted. We actually lock down what APIs are available for you to call. And we protect in the same process, so W3WP.exe, two applications running in the same process but in different app domains that are set to medium trust, in theory, it prevents those two applications from accessing each other's state or calling into each other, doing bad things, calling into each other's memory. In theory, it turns out that didn't work out so well. We publicly announced last year we changed our guidance. Please do not use medium trust. It is not a security boundary. Or any other trust level. You should just be running full trust because the trust level system in ASP.NET is no longer a security boundary. It was for 10 years and then we found out it wasn't. And there's no way to fix it. And so, we just tell you not to use it. So how should you do isolation then? If you have a situation where you have two applications, if you're a web hosting company, you have two applications running on the same server in IS and you need to protect one application from the other. Okay? That's pretty important, right? So, multi-tenoting. If I have Fowler's app and my app running on the same server and we have nothing to do with each other, I need to ensure that I can't like scan the world as soon as you're deployed to a shared host and like start reading secrets from other people's applications like their database connection strings and stuff, right? So what should you do? How do you protect against this? Application pools. Process level isolation. It's the only guaranteed security boundary in Windows, essentially. Windows is built around process isolation, okay? And so is.NET, it turns out. So place all untrusted applications into their own app pools because the application pool is the unit that then results in the actual process running. So if you go into Task Explorer, you'll see w3wp.exe. That's the process that maps to an application pool. Okay? The app runs inside that. I don't think John McCoy would agree. Okay. Okay. We should get you to introduce him to my guy. Then run each application pool under its own unique identity. Very important. Okay? So by default from IS7 and above, automatically every application pool runs in its own identity. We have those strange app pool identities which confused everybody when we released IS7. It's like, oh, it used to be network service which just worked and now it says app pool thing and like nothing works anymore, right? So everyone just changed it back to network service. Which is fine if everything on the server runs at the same trust level. But if you're trying to do multi-tenanting, every app pool has to be running as a separate user account, right? It's the only way you're going to restrict access to each other. And since Windows Vista and above, Windows is at that really cool process isolation. One process cannot call into another process at all unless they have a pre-agreed token, blah, blah, blah, blah, stuff I don't understand. And so follow the guidance. There's a great link there, Knowledge Base Article 2698981, where we basically admit that we're changing our guidance and don't use medium trust. And we show you how to set up this. If you're using IS7 and above, we have this special application pool thing that will just create, basically it creates a user account on the fly as the app pool starts. And you can use that user account to set ACLs and give your database access and all type of stuff as well. If you're running in a domain, then generally you'll create domain accounts anyway. And you'll run your app pools using a domain account. If you're a hosting company, please don't use medium trust. If you're using a hosting company and they still run in medium trust, move to a different hosting company, no. Talk to them. Take them to read this Knowledge Base Article and then get them to move off medium trust or send them to me and we'll talk to them. Okay. App settings. Great feature.net 2. So there are a whole bunch of settings that you can set in app settings. These app settings is the string based one, not the strongly typed one, right? Magic string key, magic string value, magic happens, right? Turns out it's not just there for you. We have a whole bunch of magic strings that we know about that if you put in app settings, we change ASP.net. And you'll be going, well, why isn't it just first level config? Why did you put in app settings? Why don't you just add a new element in the configuration schema to let me do this? Well, a lot of the times when we do a security fix and we send out a patch, we'll add a back door that lets you turn the patch off. We have to because a lot of these security fixes break applications, compatibility. And we have to give you a way to roll out the patch, but have it turned off so that while you're rolling out the patch, say in a web farm, where you can't roll out the patch like at once to 20 servers, you can only do it one at a time, you have to be able to in your application turn the patch off before it even exists. So we can't add schema because that's strongly typed. It has to be a magic string. So we give you the switch to turn it off. You set that in your app, you redeploy your app, okay? Then you go through and you redeploy the fix to every server. And once that's done, you just redeploy the app with the switch removed. And now you're secure, okay? That's the only time you should ever use these settings, these app settings to turn off these fixes. The only time you should ever use it. And there's a link. Hopefully this one works. They are documented. We did the work of documenting every single app setting last year because there was a lot and we added more in.NET 4.5. Come on, network, it's a really good list. Do, do, do, do. Really? There we go. Cool. So this documents all the magic keys that ASP.NET itself supports to turn things on and off. Now some of these are marked as, you know, important. This thing should only be modified by advanced developers. But of course, everybody goes, well, I'm advanced. I found the documentation. I must be advanced, right? I even knew it existed. Some of them are marked a little bit more forcefully like this. Setting this attribute to true can pose a security risk. Allow relaxed HTTP username. So here's an example of someone reported a vulnerability. We issued a patch. That patch would break certain applications that were essentially taking dependency on this vulnerability. And so we needed to give you a way to turn that patch off without you only want to install it, obviously. And so we say, please do not set this. Okay? It could pose a security risk. And they're all documented. And I will admit there's quite a lot of them. Okay? It's an old, you know, ASP.NET has been, it's a mature product. 13 years as we just heard them before. Okay? So be careful. You're all path in code. Who can tell me what this method does? It's a trick question. No one can tell me what this method does. Because the method shouldn't exist. But people use it because they think it encodes URL paths. I don't know where they got that idea. Oh, wait. I see what we did there. Yeah. Don't do it, please. This method was intended to solve one problem. And it was to solve a problem in Netscape 2 handling UNC links. We should have called it make links safe for Netscape 2 href attribute. But we didn't. We called it URL path in code. And so people thought that they could use it to encode query string values or segments of a URL and that it would be safe and protect you from cross-site scripting. It doesn't. So do not use it. Do what we talked about before. Sanitize your inputs instead. Make sure that anything that's submitted as a URL is an actual URL by using the URI class. It's what it's for. And then use URL in code, which is the method that, OK, URL in code is the right one to use. So if you need to take a value and put it in the query string of a link, you're generating a hyperlink, and you need to put a value into a query string, use URL in code, not URL path in code. That's safe to put into a query string. Do not use URL path in code. We will probably delete this method in a future release of.NET. Or make it throw or something equally heinous. OK, enable VState Mac. We really, really meant it. Do not turn this off if you take anything. If you're a consultant and you deal with customers who use ASP.NET, check this every single application that you ever lay your eyes on. Ensure that they are not setting this to false. You know what you should do? We should search GitHub and see if there are any web.config files that have this set to off and then send them a polite email. He can't message you at GitHub, can he? Send a pull request that fixes it. That's a great idea. We really mean it. See, Windows Update. Well, Windows Update that changes people's code. They'd love that. Wait, that config file wasn't like that before. Patch Tuesday and we... That would be really cool. We really mean it. A crappy clip either side. We really mean it. All right, do not turn that off. Okay, reliability and performance. So we've done... What do we do? We did standards compliance and we've done security. So that's all the security stuff, okay? Have I scared anyone enough yet that they're going to go back and change their code when they get back to their workplace? Come on, it's got to be worth my time. I see some nods. No one's putting their hands up, but people are nodding. So moving their eyes up and down or looking away like this or looking like this for the other people who have done it. So good. I got through to some people. Okay, reliability and performance. Whereas these two events, pre-send request headers and pre-send request content, anyone using these, they're pretty rare. Okay, someone put their hand up. Okay. Try to avoid them. Registering for these events from within managed IHDB module. So if you're using them from a native module, that's okay. ISNative module. Okay? If you're using them from a.NET, ASP.NET, IHDB module, they have issues. Okay? So use the native ones instead. I don't know what the issues are. My runtime guy said, don't actually give me notes. No, he didn't give me notes. That's a shame. But don't use them. They cause issues with asynchronous requests, doing overlapping things and like sending headers at the wrong time in the pipeline. After headers have already been sent, it's possible to do it using the managed API. The native API just solves all that for you. So don't use them. Even if you're not using them directly, you may be using a component that you bought or downloaded that is. So anyone here ever used a large file upload component for ASP.NET? Anyone? No one? A couple of people hands, okay. A lot of those use these events in the past, okay? Because they want to do stuff just before they send a request back or as the request is coming in. So, okay, async page events. So this is in web forms to do with the task-based asynchrony that we added in.NET 4.5, which I spoke about here last year, I think, or the year before. Try to avoid writing async void methods. So you can do protected void, protected async void page underscore load and then write a wait code inside your page load. And that does work, okay? Work for the simplest of scenarios. But what we want you to do really, and same for button click handlers, you can do like a protected void, async void, my button underscore on click, some async code. And it kind of works, ish, in the really simple demo cases it works. As soon as you do anything more complicated, you can introduce race conditions in your code. So what you should be using is the first class API for telling the page that there is going to be async work. And that is page.registerasync task, which has been around since.NET 2, okay? It's been there forever, but we updated it in 4.5 to support task returning delegates, asynchronous lambdas, okay? You should be using that. And what that does is it queues up the async work, when you call it from page init, page load, button click handle or whatever it is. And then once you get to pre-rendered complete, then it runs the async work in a coordinated fashion. And because that method that you registered with that method, you have to give it a delegate, that must return a task. We have an object that will tell us when that async work is finished. Async void, we have no way of knowing when that async work is truly finished. We can kind of track it using the synchronization context because it raises an event when async work starts and then when it finishes. But if async work kicks off more async work, that kicks off more async work, then that can just all fall over, okay? But if you use registerasync task, it just works. And do make sure that you set HTTP runtime target framework equal to 4.5 if you're doing any type of task async in web forms or in MVC or web API or signaler, okay? If you're running on 4.5, make sure you set target framework equals 4.5. That flips in the new synchronization context that we added in.NET 4.5. It's opt-in. We don't do it by default because it changes behavior of async work, okay? So you need to turn that on if you're doing anything with tasks. Now it's good on net. If you do file a new project in Visual Studio 2012, it's turned on for you by default, okay? Fire and forget work, try and avoid having code in ASP.NET where you handle a request, so in an MVC action method or in a web forms page load or an Ajax handler or something. Try and avoid kicking off fire and forget work. Thread pool queues a work item, starting a timer that calls a delegate every so many seconds from within ASP.NET. The reason is at any point in time we may decide just to completely destroy the app domain while that async work is running. We generally won't do it while a request is running, but if you fire off fire and forget work, by definition the request will be over very shortly afterwards and that work will keep going, right? Because it's fire and forget. You don't care about it. So if you do that, we can just tear down the app domain and you'll get all types of strange exceptions in your background work and we may even corrupt your state. And that can lead to really bad things. Give you a writing software database in such a way or a text file and now we've corrupted your text file. Okay, because we just literally crashed your thread. If you want to do background work in ASP.NET, first of all, don't. Move it to a different process. Write a Windows service or if you're in Azure, use a worker role, queue it and then have some other process pick it up where you manage lifetime yourself. If you absolutely must do it inside ASP.NET, you can check out web backgrounder. It's a NuGet package that Phil Hack wrote that lets you schedule background work in ASP.NET, work that happens on a background thread inside the ASP.NET app domain, but it listens for the correct events. So when the app domain gets torn down, we give it a chance to finish the work gracefully before we destroy the world underneath it. So look at web backgrounder if you need to do that type of work rather than just starting timers in AppStart or doing thread pull.q as a work item, okay, use web backgrounder. Okay, the request entity body. Try to avoid reading request.form input stream before the handler. This is pretty advanced stuff. So if you're writing a handler and you want to be able to get the actual network stream that represents the request coming in from the client because you want to do large file upload. You can do that like the stream as it comes in to do whatever it is, log it out or something like that. You shouldn't really do that before handler execute, okay? You don't want to do that. Or request.form, by the way. You really want to try and defer it to when handler is executing. Handle execute is the event where your action method in MVC runs or your page in web forms runs like page.NET will fire, okay? That's the handler. The page or the MVC controller is the handler and handler execute will execute those things. If you read request.form or input stream before that, either from a module, that's generally where you'll do it from, from a module, then you can cause issues. What you want to do instead is use these APIs here. Get buffless input stream and get buffered input stream. So get buffless input stream was added in 4.0 and get buffered input stream was added in 4.5. And they do what they say. A buffless input stream gives you the raw stream from the request, which you call before handler execute, but be warned. If you call this API, you're telling ASP.NET, I am taking over this request completely. I don't care what was going to run after me. I am in charge of this request from now on, and I'm going to read from the stream manually, which means things like request.form won't work because they usually get populated by ASP.NET by reading the stream. But if you start reading the stream, buffless input stream, then you read the stream. You read the bytes into your own variable, which means no one else can read them. It's a stream, right? Once you read them, you can't look at them again. It's not a buffered stream by default. It's to literally a network stream. So if you call this method, you can't call request.form. You can't call request.files because that won't work. If you call get buffered input stream, you can. Get buffered input stream will give you the bytes as they come up, but it will also buffer them away into memory or spool them to disk so that if later on in the request lifecycle you do call request.form, it will still work because we took a copy of it before we gave it to you. Okay? So low-level APIs, but we've seen issues reported where people had called these events and then they called server crashes and types of things because they're doing things in the wrong order, or they're doing things after certain things have happened or things like that. Anyone actually using these? Anyone actually used done input stream processing in ASP.net? Okay, so that all fell in deaf ears. Never mind. If you ever need to do it, check out those. Okay, response.redirect, and this is more of an be aware rather than a don't do this or do something else. If you call the overload of response.redirect, which just takes a string, that cancels the request. So when you call response.redirect string, the next line of code after that doesn't run because we call response.end, which throws a thread abort exception synchronously inside your code and literally tears your function call, your stack in half. Okay? You were calling this function, you were this point in the call, you called response.redirect, and then we just canceled the thread by calling thread abort so we could return it. Okay? Which may or may not cause really odd things to happen in your application, depending on what you were doing. Okay? So we call it a function type of state in memory and then we just kill it on the fly. For async when it's handlers, response.end does not abort it, but code execution continues. So the behavior that differs whether you're doing async programming or not. In async programming, we change the behavior. When you call response.redirect, sorry, when you call response.end in async programming, it doesn't actually end. We let the rest of the request run through and then we let it finish. So basically don't recall response.end from an async handlers. To end an async response, you have to return the task that you returned originally from the async method that we showed in the signal I talked just before. That's when the request will end, only when that task finishes or if you're using the old pattern when the end method, when you call the callback that was passed into before, into begin, sorry. So response.end doesn't do anything in async. If you want to redirect the response, you should be using the appropriate method given to you by the framework you're using. Now if you're using web forms, response.redirect is fine, but you just need to be aware of what's going on. There is an overload of response.redirect that takes a boolean, which you can say redirect, but don't thread abort. Redirect after you've finished executing the page. In MVC, you'd return a redirect result. Do not call response.redirect from inside your action method. That is absolutely the wrong thing to do. You need to return a redirect result from your action method. And then the MVC pipeline will see that at the appropriate time in the lifetime of the request and then send it back. Now remember, this section is about performance and reliability. We're not saying that this is going to cause issues immediately, but it does make your app less reliable. It may cause issues under load. Having some of these things introduces certain race conditions or possible memory corruption or stack corruption problems that you may not see until you get lots and lots of load or you may see one in a million requests. But they can be the hardest bugs to track down. I'm sure you all have experiences of looking in the event log and seeing an obscure error from ASP. You have no idea why it was there. You never saw it again. You see it once every week and you don't know why it's there. A lot of the time it's these type of things. You may not be doing it. You might be using some code, a component that you bought or something you downloaded from the Internet that's doing it and you don't realize it. Enable ViewState and ViewState mode. Try to avoid enable ViewState. Enable ViewState has always been there. It's how you turn off ViewState. It's on every control in the hierarchy and web forms, but when you turn it off, there's no way to turn it on again underneath that control. If you turn it off at the page, it's off. You can't turn it on for one control. ViewState mode, which we introduced in.NET 4, lets you do granular ViewState control. You can set ViewState off at the page level, which we thoroughly recommend, by the way. Just turn ViewState off by default. Set ViewState mode equals to disabled at the page directive level. At page, ViewState mode equals disabled. That will set ViewState off for the page. Then on the controls that your testing has determined need ViewState to work, turn it back on just for that control. That will save you an awful lot of ViewState that you otherwise would be taking up, which is one of the biggest bugbears that people have with web forms. It's really easy to fix in.NET 4. Just turn it off and then turn it on for the controls that need it. You'll see your ViewState shrink dramatically. Has anyone doing this already? People know about this already? No? One person? Two people? Good. Okay. SQL membership provider. This is the inbox provider that we shipped forever for doing membership support in.NET, using SQL Server. We replaced this with an out-of-band component called the universal providers, system.web.provider. It's a new get package. It's used by default in the templates since, I think, Visual Studio 2010 Service Pack 1. It's in all the templates in Visual Studio 2012. It works with all databases that Entity Framework supports because it uses EF. It doesn't talk to SQL directly. It uses EF. It'll work with SQL, Azure SQL, SQL Compact. If you have the Oracle Entity Framework provider or the MySQL Entity Framework provider, it'll work with those as well. Just be mindful of that if you're still using SQL membership provider. The other thing is that we made some improvements. The universal providers have, they're better. If you're still using SQL Server, these ones are better. They don't use stored prox. They're a bit more flexible. They're faster. They're better written. We can update them out of band. They're not in the framework. They're on new get. They're easier for us to improve as we go forward. If you're deploying to Azure, you really need to use these ones. Long running requests. That is requests that run longer than 110 seconds. Really, any request that runs longer than a couple of seconds is by definition a long running request. Requests generally should be over very, very quickly. That's what we want our things to do, be quick as possible. That's how HTTP was designed to work. Some interesting things happen when you let your request run over 110 seconds. By default, that's the request timeout setting. Depending on what framework you're using, whether you're running a raw handler or web forms or MVC, we may or may not just destroy the request and give you an exception, request timeout exception. Things like the session object. Who's using session state in ASP.NET? Be grudgingly. Session state in ASP.NET is not my favorite feature. I own ASP.NET as a feature-wise. I don't like it. Long running request. Long running takes a lock on the session object. When two requests from the same user come in at the same time, perhaps because your page makes two Ajax requests or while the page is still loading, they hit a button which makes an Ajax request, we block the second request while the first one is still active because we've locked the session object for that user. A lot of people have run into this when trying to do long polling in ASP.NET in the past. After 110 seconds, we release the lock. Maybe that's a bad time. Maybe you were in the middle of doing some session work and now suddenly we release the lock and all hell breaks loose. Your session stuff that you were saving doesn't get saved. Or the read that was going on suddenly happens when it should have been blocked. So don't do it. Don't try and have long running requests that are greater than 110 seconds that use session state. Just try not to use session state if you can avoid it. Also don't perform blocking IO operations. I think everyone's aware of what a blocking IO operation is now after two years of node being on the scene. We've talked about async a lot in the last two years. We now have async APIs for all of the type of IO that you would want to do in.NET, whether it's file, network, web service, socket or database as of EF6. ADO.NET already supported it but EF6 supports it at the ORM level. So you can do asynchronous OI now from web forms or from MVC or Web API signal and free up that thread. So for long running operations though in general, you better off to use web sockets if you can or signal R. Just inject signal R anywhere web sockets is said. As it has a much lower per request overhead. The other thing a long running request will do is use memory. Even if it's async, an async request that's long running won't use a thread when it's idle but it still uses memory. I mean there's still data stored in memory that represents that request. But a web socket request in ASP.NET, special API introduced in.NET 4.5 is a much lower per request memory overhead. When you call accept web socket request and you give us the delegate, we unwind the request, free up most of the memory to do with that request and then we invoke your delegate with a restricted context, not the full HTTP context, just a small set so that we free up a lot of memory. It's about five times less than a full request. Now signal R just does the right thing. If you use signal R, we use web sockets when we can. Otherwise we use long polling or forever frame or server center events and it's async so we just try and do the best thing we can. And that is the end of my talk with other people that I didn't do the talk with. That's my boss, Cool School. His name is Carl Scott Hunter, Cool CHR. And you all know Scott Hansman. So I have two minutes. If anyone has any questions, I can answer them right now on stage or ping me on Twitter and I'll do my best to answer them. Otherwise thanks for coming along. Any questions before I pack up? No? Okay, awesome. Okay, awesome. Okay, awesome. Okay, awesome. Okay, awesome. Okay, awesome. Okay, awesome. Okay, awesome. Okay, awesome. Okay, awesome. Okay, awesome. Okay, awesome.
 I'm just waiting for my machine to boot up.  I just finished another talk and my machine decided to have a bit of a rest in between  as I walked over here.  So I'm trying to get it started up again.  We're going to talk about some interesting stuff today.  I've given this talk a couple of times already.  It's really designed around, well, I'm probably going to hurt some people's feelings in this  talk.  This is advice from the ASP.NET team based on things that we've seen people do in the  wild.  Given that ASP.NET is a fairly old framework now, it's over 10 years old.  There's a fair bit of legacy.  There's some security things that are interesting to talk about that have been fixed along the  way, but some people may not know about them and are doing things incorrectly.  There are some APIs that we wish that we'd never invented or they serve their purpose  and now we don't want you to use them anymore.  So I'm going to tell you about those.  For every one of the ones I tell you not to do, I will give you an alternative of what  you should do instead.  As I said, I'm pretty much guaranteed to offend at least one person in this room, with what  I'm about to tell people not to do.  If I'm really good, I'll freak someone out enough that they call back to work and ask  them to pull down their website immediately because they're doing something that's completely  insecure.  We'll get there.  Come on, come on, laptop.  Who was in my last session with David?  There is no coding in this session.  This is all me talking about APIs and what not to use and what to do.  There is a PowerPoint and I link off to some examples and things.  There is no coding in this demo.  I'm coded out today.  Come on, come on, come on, come on.  How many people here have been using ASP.NET for two years or more?  Okay, three years or more.  Keep your hand up.  Four years or more?  Five years or more?  Six years or more?  Seven years or more?  Look at the stayers.  Eight years or more?  Now dropping off now, nine years or more?  What are we back to?  That's out of 2004?  Ten years or more?  Eleven years or more?  Came out in 2002, by the way.  This is where it stops unless you use the beta.  Twelve years or more?  Thirteen years or more?  First beta?  Who used ASP Classic?  Okay, a lot of people.  Okay, here we go.  It's up.  That filled in the time beautifully.  Plug this in.  No God's willing.  This will just work this time.  I want that one.  And just for good measure, I'm going to paste it out to the desktop.  Oh, come on.  Come on.  There we go.  I was tricking you.  No, do not start in safe mode.  Just start.  There we go.  All right.  The last time I gave this talk, there were a lot of Scots on stage.  Scott Hack, the little-known Scott Hack.  This time it's just me.  All right.  ASP.net, don't do that.  Please do this instead.  Really obligatory disclaimer written by the security guy on our team that we never question  about anything he says about security.  This is not intended to be like the complete guide where if you follow everything in this  guide, in this presentation, then that's it.  You're golden and we're signing off on your application.  Ship it.  You're never going to have any problems.  This is not that, of course.  This is stuff that we would like to bring to your attention based on previous guidance  that we've given you and perhaps we're changing our guidance.  We only intended to call out the most common, incorrect, or undesirable uses that we encounter  when we look at people's applications.  People file bugs.  They send up repro's and we go, oh, you're doing that.  Please don't do that.  This is a collection of those things.  We've broken the talk into sections.  The first one is around standards compliance.  We're talking about HTML standards compliance.  JavaScript says that type of thing first.  Control adapters.  Whoever used control adapters in web forms.  There's a lot of web form stuff in here, believe it or not.  Yes, control adapters.  Control adapters were originally designed to support mobile controls.  We had this fantastic feature in ASP.net 2 about mobile controls.  You drag a text box, a mobile text box, onto the page and it would render different HTML  or WML or XHML or XML depending on what the device was.  It did that using our browser capability system and these things called control adapters.  The one control could adaptively, in a pluggable fashion, change what it renders at run time.  We don't want to support it anymore, so please don't use it.  It's an old technology.  We deprecated the mobile controls themselves, but a lot of people are still using control  adapters.  We would prefer that you do this using CSS, render standards compliant HTML, either using  a control that you wrote or one of the ones in the box or just basic HTML.  Then you use CSS, media, queries, responsive design, all that good stuff to do the mobile  specific logic in your application.  Who is doing the stuff on the right today?  Responsive design, media, queries, great.  Perfect.  Who has ever used the stuff on the left to do mobile websites?  Anyone?  Okay, good.  It served its purpose.  Before we had CSS, there was a time, it was, or devices that didn't support CSS, you had  to do this.  Now we just sort of assume that everyone has a smartphone or at least a phone with a  browser that supports some level of HTML, CSS, so don't use them anymore if you can avoid  it.  Okay, style properties on controls.  This is code behind textbox.style.editititem template, alternate item font, four color  opacity level.  There are hundreds and hundreds of these properties on the web forms controls, and I  hate them.  You're in your markup and you're doing grid view, colon, blah, blah, blah, and then you  hit E and you get a list of intelligence with 100 items in it that's just full of this  garbage.  Okay?  You shouldn't be setting your CSS in line on your HTML anyway.  We all know that.  You should be attaching it via CSS.  Now I would love to, in a future version of ASP.net and web forms, literally delete  all of these properties.  Just get rid of the style collection class and get rid of the styles property and force  people to use CSS to do it the right way, quote, unquote.  So please, if you are using this today, very common if you're doing things like data binding,  you're handling the on item data bound event, and then you go in and you navigate through  the cells, look at the value.  If it's less than zero, then you say, oh, current cell.style.fourcolor equals color.red.  Okay?  Don't do that.  Do current cell.CSS class equals string negative.  Then add a CSS style sheet with a class called negative, has a semantic name, and set the  four color of the font that way.  Much more maintainable.  You don't have colors and all types of style crap embedded in your C sharp.  We will be able to clean up this intelligence in the future for you as a result.  Please don't use style properties.  Page and control callbacks.  It's introduced in.NET 2.  This is the thing that lets the grid view do paging and sorting without having to do  a full page request.  This is not update panels.  That was different.  Anyone used page or control callbacks?  Okay.  Also known as page methods.  You could have a static method on your page, and then you could invoke it using Ajax.  Okay?  Kind of nice.  Ish.  Just don't use them.  We have better ways of doing this now.  These cause some issues with some of the newer stuff.  Friendly URLs, the stuff we added in web forms this year that gives you the extensionless  URLs for web forms, doesn't work well with this.  Routing does not work well with this.  If you want the modern URLs, the ability to control your URLs using routes, then have  them separate to your pages and your controls and whatnot.  It doesn't work well with page callbacks and controls with callbacks.  Just use anything else.  Anything but that.  Okay?  Update panel is fine.  Update panel is an amazing piece of technology.  It really is.  I've seen the patent.  Okay?  It's patented.  It's really cool.  Just don't abuse it.  Okay?  Know how it works.  Understand what's going on, and then use it for the portion of the page that you want  to use it for, and just be mindful of it, and test it, you know, to perform this test  and whatnot.  Just use Ajax MVC action methods, web API, signal R, whatever it is you want to do to  get that Ajax-y type non-full page refresh back, but try and avoid page and control callbacks.  If you're using the grid view or a control that itself uses control callbacks, just turn  that feature off or don't enable it in the first place.  None of the controls will use it by default.  You have to turn it on in order for it to work.  So just don't turn it on.  Okay?  Capability detection.  So we have this feature in ASP.NET called BrowserCaps or Browser Capabilities, which  is this massive XML database that's installed on the server that says, hey, this browser  with this user agent string is IE whatever or Firefox whatever, and it supports ActiveX,  Cookies, this type of image format.  It has this wider screen, blah, blah, blah, blah, blah, blah.  Okay?  And there are third party vendors who sell expanded versions of these databases for mobile devices  and things.  And people have used this for a long time, the mobile controls that I talked about before,  they use this.  But we generally now know that doing browser detection or capability detection from a static  reference is generally frowned upon.  Okay?  We don't like doing that anymore.  We don't use the agent sniffing.  We don't test for one thing and then assume that something else will be there because  that thing was there.  We know that's bad, right?  So we should be doing feature detection.  So we should be lighting up our features in the client where we can test for those features  in real time using JavaScript or clever CSS tricks.  Oh, I know that this browser supports ping images because I tried to write some code  that should result in this element appearing and it didn't.  Or now I know it didn't support ping images, but you get the idea.  So we have tools like Modernizer, great library from a couple of guys, Guy at Google, a guy  to a few other guys, Paul Irish, a couple other guys.  We ship it in our templates.  There's a client-side library that helps you determine what are the capabilities of  the current browser, but it does it using feature detection, not via some big static  list of features that it understands.  Okay?  So please use feature detection and not capability detection.  Okay, so that's everything about standards compliance.  I'll stop ranting about that now.  And we'll talk about security.  This is where it gets a bit scary.  Okay, so request validation.  Who knows what request validation is in ASP.net?  Okay, is that really annoying thing that gets in the way when you try and post back anything  that looks like HTML?  Yes, you turn it off, which is what most people end up doing, which is bad because it means  that we probably didn't design the feature very well.  So the idea behind request validation was that, hey, let's not have the developer have  to worry about cleansing all the input coming in from the browser on the odd chance that  they may echo that input back out to the browser, or they may inject that input into  a SQL string.  Okay?  We'll detect, detect any malicious type of content.  Oh, there's an angle bracket.  Oh, there's a question mark after or whatever.  Shut down the request before your handler even gets assigned.  So it's a module that runs really, really early in the HTTP pipeline in ASP.net.  It inspects the request.  So it looks at the form body.  It looks at the query string, and it looks at the request path.  And it sees anything it doesn't like.  It just kills the request on the spot.  You get that yellow screen of death, hey, a potentially dangerous token was found and  blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah, blah,  and you go, ah, damn it, you turned it off.  You never use it again.  Now, we did add features in version 4.0 that let you do it more granularly.  So in MVC, for instance, you could say, I just want this text box in MVC to not go through  request validation, but let the rest of the page go through request validation.  That was nice.  You could turn it on for the whole page, but just not have it on for this control.  And I'm sorry to say we actually did the work in ASP.net 4.5 to support that same thing  in web forms.  And then we decided that we didn't want people to use it anymore after we did all the work.  So we do not want you to depend on request validation.  And there's a reason.  It's because request validation is a game of whack-a-mole.  We find or we get reported a vulnerability where browser foo version X doesn't like it  if you send in a request with a form body with this seven-character string escaped with  Unicode 7 or something crazy.  That gets through request validation.  So now we have to patch request validation, send it out to the world.  That's a really expensive effort.  And we just can't win because this stuff changes all the time.  There are new browsers every week, new versions that introduce new vulnerabilities, and we  can't keep request validation up to date.  And anyway, it's a bad idea.  It actually encourages bad practice.  We're giving you a crutch that you shouldn't be relying on.  So what should you do instead?  Who knows what you should be doing instead?  Come on, I have nothing to give you, but I'll be impressed if someone can give me the answer.  What's the answer?  No one knows.  So encoding is one, half of it.  Well done, sir.  You need to encode your output, whether it's going into SQL via a parameter or going into  the HTML via HTML encoding, and you need to validate your input.  If you're expecting a URL from as the input from some text box that the user is typed  into, validate it as a URL.  Don't use Regex for God's sake.  Don't use Regex.  We have types in.NET.  One of the nice things about.NET is this big library of useful features.  And then we have a type, like system.uri, which you can pass the string into.  And it will tell you whether it's valid HTTP, sorry, a valid URL or not.  And it is written to the spec.  So if it says it's a URL, it's a new URL.  If it says it isn't, it isn't.  You don't have to do that.  So validate the input on the way in.  If it should be a number, make sure it's a number.  If it should be a string without certain characters, write a parser.  Maybe you could use Regex in that case.  If it should be an email, what's the best way to validate email?  Send an email to the address and wait for a reply.  I am not kidding.  It is the best way and really the only way you will ever truly guarantee that the email  address that someone has written in is a valid email.  It may look like a valid email, but it's not valid unless they can get an email on it.  And if you've read the email spec, including supporting international characters in your  email, which all modern clients do, modern mail servers do, I can type an email address  that contains a domain which contains a Unicode extended character pairs.  Chinese, Kanji, and hieroglyphics and all types of windings, whatever I want.  Emoji characters.  I can have an email totally made of emoji.  Does your Regex support emoji email?  I pretty much guarantee not.  So all you should really do is go, it's an email.  I know it has to have an at sign in there somewhere and it can't be the first character  and it can't be the last character.  So check for that.  That's fine.  Although technically you could escape the at sign.  So anyway, you could do that and then once you get the string, send an email to it.  And then just say to them, hey, we got your email address.  That's great.  Sometime in the future you'll get an email.  Please reply to it and then we'll activate your account, whatever it is that you're doing  with that email.  And then on the way out, always encode your data.  So if you're in Razer, good news.  It does it for you by default.  You just do at foo where foo is some variable, a string or an int or some user provided data,  something you got from a database that your business users might have had access to.  You need to protect against that as well.  Then just do at foo.  It'll automatically HTML encode it for you.  There is no way they can get bad data into the page.  That sort of result in a cross-site scripting vulnerability in your page.  If using ASPX in version four of.NET, we introduced angle bracket percent or bumblebee  as we call it, colon.  So angle bracket percent equals should never, ever, ever, ever, ever be used anymore.  Just don't use it.  You can't do it in Razer.  There's no way to say don't encode it.  The way you say don't encode it is to give it a variable of type IHTML string.  Then it will go, oh, it's HTML already.  I don't need to encode it.  You have explicitly stated that this is not a string.  It's an HTML string.  So don't use and colon supports the same thing.  Just don't use equals anywhere.  Who currently knows that they have angle bracket percent equals in their site?  It's the first thing you're going to do when you get back.  Seriously.  And if you're using data binding in web forms and you're using angle bracket percent pound  or hash and then like bind or eval, in.NET 4.5, we added hash colon, which does the same  thing.  It performs a data binding expression, gets the value, and then encodes it automatically  for you.  If you're not using.NET 4.5, I'm sorry, you'll have to manually call HTML, you know, HTML  with a servi utility dot HTML dot HTML encode and then pass in the result of the binding  expression.  If you're using two-way data binding, the bind angle bracket percent colon, angle bracket  percent hash bind, who's using that?  Anyone using that in web forms?  Okay.  There is no way to encode that unless you're in.NET 4.5.  So upgrade to.NET 4.5 and change that to hash colon bind, then you're safe.  Okay.  Excellent.  Ah, yes, because that's required for.NET 4.5.  It is.  Yes.  You have to actually encode the values that you're binding to.  So the thing you're binding to has to already have been encoded.  Okay?  That's the way you'd have to do it.  And don't forget about JavaScript.  If you're emitting stuff from server code into a script block or into a CSS attribute  into style equals, you have to do different encoding.  They're different languages.  You can't HTML encode in there.  And we have methods for those.  JavaScript string encodes, CSS encode, URL encode.  If you're emitting a string into an href attribute, that's not HTML anymore.  It's a URL.  Again, you have to correctly encode the value to ensure that people aren't trying to pass  values in through a URL.  Which people do.  It's how you get cross-site scripting in your site.  It's a really, really nasty bug to have.  All right.  Cookulous, FormsAuth, and Session.  Another brilliant feature of ASP.NET since 1.0, who's using, who knows what Cookulous,  FormsAuth, and Session is?  Okay.  Who's using it?  Great.  I'm doing everything.  Who has used it in the past?  Anyone?  Okay.  Good.  So in the end, basically, it was designed in the early days when a lot of browsers didn't  support cookies.  We cared about browsers that didn't support cookies.  And we wanted to use FormsAuth and Session.  But you know what?  It just don't use it.  It's insecure.  Okay?  You should never be passing around this stuff in the URL, which is what Cookulous does.  It depends on the URL.  It's just a really, really bad idea.  So enable require cookies for these features.  There's actually a flag that says require cookies.  Okay?  So you can turn that on to ensure that you'll never accidentally support a browser that  turns up with cookies turned off.  And then you'll start passing around tokens that are potential security vulnerability.  And consider using only SSL cookies for sites serving sense of information.  So that means if you're writing a cookie or using FormsAuth, then if that cookie contains  sensitive info, like a authentication ticket, you should only be sending it over SSL.  And the cookie should be marked as only being able to be sent over SSL.  There's actually a secure flag on a cookie, and the browser will not send it unless it's  an HTTPS connection.  And that's all configurable in ASP.net.  Whether you create the cookie yourself in code behind, there's a flag on the cookie,  is secure, set it to true.  Or if you're using FormsAuth or Session, you can set that flag as well in the configuration.  Enable ViewStateMac.  Oh boy, this one's a good one.  Who knows what this is?  Enable ViewStateMac.  Everyone knows what ViewState is, right?  The thing we love to hate?  So ViewStateMac is the thing that ensures that the ViewState that was posted when you  do a Form post is valid.  It ensures that the ViewState came from the server originally.  Because if you think about what's in ViewState, what's in ViewState?  It's state to do with the controls that were rendered, or it's stuff that you put in there  manually.  And whatever is in that state affects what the controls do.  It may rehydrate a bunch of properties that you would set after page load, or it may trigger  an event and then call into your code.  So you really want to make sure that when someone does a post to your website to an  ASPX page, that the ViewState payload that comes up, which is a base 64 bunch of characters,  we undecode it and then basically we deserialize it into binary types and then we run code.  You should already be worried at this point.  You need to make sure that that's a valid piece of ViewState that only came from your  server.  You need to ensure that it hasn't been tampered with.  Someone hasn't tried to manipulate the ViewState in such a way that they can make your code  do something you didn't want it to do.  So do not ever, ever, ever turn this off.  We should never have let you turn this off.  Has anyone here ever turned this off?  This is a setting in the page or in web.config.  Enable ViewStateMac equals false.  Has anyone ever done it?  Has anyone ever admitted to doing it now that I've said that?  But I'm not using ViewState as not a valid excuse.  Unfortunately, we called the property enableViewStateMac, but then we used it to enable other things  that don't do with ViewState, like ControlState and event validation and all the other things  that web form sticks in hidden variables and then uses to sort of rebuild the page when  you post back.  It's incredibly important that you never, ever turn this off and in a future version  of.NET, we will remove the support for this.  If you set this to false, we'll just blow your application up.  It is incredibly dangerous.  There's actually unpublished vulnerabilities about this thing.  Yeah, so just tease us forever, allowing it.  So here is a public vulnerability.  I get the hyperlink.  Where's the hyperlink?  Ah, give me the hyperlink.  It's, you know what?  I'll format it as a hyperlink.  Seriously, PowerPoint, that was a hyperlink.  Last time I did this.  There is actually a public known vulnerability.  If you turn this off, which it is not by default, of course, it is on by default, meaning it's  secure.  But if you turn it off in your app, there are publicly reported vulnerabilities that you  could be susceptible to that will enable cross-site scripting in your app.  It means I can make a malicious request to a page where this is turned off.  I can manipulate the view state because it's not encrypted and it's not verified.  It's not signed with a Mac, HMac.  And then I can tell your site to do something that you didn't intend it to do.  Get it to render stuff into a page for another user that makes it run my JavaScript, for  instance, really, really bad stuff.  Medium trust.  Who uses medium trust in ASP.NET?  Really, everyone's running full trust?  Really?  Who doesn't know what medium trust is?  So,.NET supports a partial trust system.  The idea of having your application code run inside an app domain that is restricted.  We actually lock down what APIs are available for you to call.  And we protect in the same process, so W3WP.exe, two applications running in the same process  but in different app domains that are set to medium trust, in theory, it prevents those  two applications from accessing each other's state or calling into each other, doing bad  things, calling into each other's memory.  In theory, it turns out that didn't work out so well.  We publicly announced last year we changed our guidance.  Please do not use medium trust.  It is not a security boundary.  Or any other trust level.  You should just be running full trust because the trust level system in ASP.NET is no longer  a security boundary.  It was for 10 years and then we found out it wasn't.  And there's no way to fix it.  And so, we just tell you not to use it.  So how should you do isolation then?  If you have a situation where you have two applications, if you're a web hosting company,  you have two applications running on the same server in IS and you need to protect one application  from the other.  Okay?  That's pretty important, right?  So, multi-tenoting.  If I have Fowler's app and my app running on the same server and we have nothing to do  with each other, I need to ensure that I can't like scan the world as soon as you're deployed  to a shared host and like start reading secrets from other people's applications like their  database connection strings and stuff, right?  So what should you do?  How do you protect against this?  Application pools.  Process level isolation.  It's the only guaranteed security boundary in Windows, essentially.  Windows is built around process isolation, okay?  And so is.NET, it turns out.  So place all untrusted applications into their own app pools because the application pool  is the unit that then results in the actual process running.  So if you go into Task Explorer, you'll see w3wp.exe.  That's the process that maps to an application pool.  Okay?  The app runs inside that.  I don't think John McCoy would agree.  Okay.  Okay.  We should get you to introduce him to my guy.  Then run each application pool under its own unique identity.  Very important.  Okay?  So by default from IS7 and above, automatically every application pool runs in its own identity.  We have those strange app pool identities which confused everybody when we released  IS7.  It's like, oh, it used to be network service which just worked and now it says app pool  thing and like nothing works anymore, right?  So everyone just changed it back to network service.  Which is fine if everything on the server runs at the same trust level.  But if you're trying to do multi-tenanting, every app pool has to be running as a separate  user account, right?  It's the only way you're going to restrict access to each other.  And since Windows Vista and above, Windows is at that really cool process isolation.  One process cannot call into another process at all unless they have a pre-agreed token,  blah, blah, blah, blah, stuff I don't understand.  And so follow the guidance.  There's a great link there, Knowledge Base Article 2698981, where we basically admit that  we're changing our guidance and don't use medium trust.  And we show you how to set up this.  If you're using IS7 and above, we have this special application pool thing that will just  create, basically it creates a user account on the fly as the app pool starts.  And you can use that user account to set ACLs and give your database access and all  type of stuff as well.  If you're running in a domain, then generally you'll create domain accounts anyway.  And you'll run your app pools using a domain account.  If you're a hosting company, please don't use medium trust.  If you're using a hosting company and they still run in medium trust, move to a different  hosting company, no.  Talk to them.  Take them to read this Knowledge Base Article and then get them to move off medium trust  or send them to me and we'll talk to them.  Okay.  App settings.  Great feature.net 2.  So there are a whole bunch of settings that you can set in app settings.  These app settings is the string based one, not the strongly typed one, right?  Magic string key, magic string value, magic happens, right?  Turns out it's not just there for you.  We have a whole bunch of magic strings that we know about that if you put in app settings,  we change ASP.net.  And you'll be going, well, why isn't it just first level config?  Why did you put in app settings?  Why don't you just add a new element in the configuration schema to let me do this?  Well, a lot of the times when we do a security fix and we send out a patch, we'll add a  back door that lets you turn the patch off.  We have to because a lot of these security fixes break applications, compatibility.  And we have to give you a way to roll out the patch, but have it turned off so that  while you're rolling out the patch, say in a web farm, where you can't roll out the  patch like at once to 20 servers, you can only do it one at a time, you have to be able  to in your application turn the patch off before it even exists.  So we can't add schema because that's strongly typed.  It has to be a magic string.  So we give you the switch to turn it off.  You set that in your app, you redeploy your app, okay?  Then you go through and you redeploy the fix to every server.  And once that's done, you just redeploy the app with the switch removed.  And now you're secure, okay?  That's the only time you should ever use these settings, these app settings to turn  off these fixes.  The only time you should ever use it.  And there's a link.  Hopefully this one works.  They are documented.  We did the work of documenting every single app setting last year because there was a  lot and we added more in.NET 4.5.  Come on, network, it's a really good list.  Do, do, do, do.  Really?  There we go.  Cool.  So this documents all the magic keys that ASP.NET itself supports to turn things on and off.  Now some of these are marked as, you know, important.  This thing should only be modified by advanced developers.  But of course, everybody goes, well, I'm advanced.  I found the documentation.  I must be advanced, right?  I even knew it existed.  Some of them are marked a little bit more forcefully like this.  Setting this attribute to true can pose a security risk.  Allow relaxed HTTP username.  So here's an example of someone reported a vulnerability.  We issued a patch.  That patch would break certain applications that were essentially taking dependency on  this vulnerability.  And so we needed to give you a way to turn that patch off without you only want to install  it, obviously.  And so we say, please do not set this.  Okay?  It could pose a security risk.  And they're all documented.  And I will admit there's quite a lot of them.  Okay?  It's an old, you know, ASP.NET has been, it's a mature product.  13 years as we just heard them before.  Okay?  So be careful.  You're all path in code.  Who can tell me what this method does?  It's a trick question.  No one can tell me what this method does.  Because the method shouldn't exist.  But people use it because they think it encodes URL paths.  I don't know where they got that idea.  Oh, wait.  I see what we did there.  Yeah.  Don't do it, please.  This method was intended to solve one problem.  And it was to solve a problem in Netscape 2 handling UNC links.  We should have called it make links safe for Netscape 2 href attribute.  But we didn't.  We called it URL path in code.  And so people thought that they could use it to encode query string values or segments  of a URL and that it would be safe and protect you from cross-site scripting.  It doesn't.  So do not use it.  Do what we talked about before.  Sanitize your inputs instead.  Make sure that anything that's submitted as a URL is an actual URL by using the URI  class.  It's what it's for.  And then use URL in code, which is the method that, OK, URL in code is the right one to  use.  So if you need to take a value and put it in the query string of a link, you're generating  a hyperlink, and you need to put a value into a query string, use URL in code, not URL  path in code.  That's safe to put into a query string.  Do not use URL path in code.  We will probably delete this method in a future release of.NET.  Or make it throw or something equally heinous.  OK, enable VState Mac.  We really, really meant it.  Do not turn this off if you take anything.  If you're a consultant and you deal with customers who use ASP.NET, check this every single application  that you ever lay your eyes on.  Ensure that they are not setting this to false.  You know what you should do?  We should search GitHub and see if there are any web.config files that have this set to  off and then send them a polite email.  He can't message you at GitHub, can he?  Send a pull request that fixes it.  That's a great idea.  We really mean it.  See, Windows Update.  Well, Windows Update that changes people's code.  They'd love that.  Wait, that config file wasn't like that before.  Patch Tuesday and we...  That would be really cool.  We really mean it.  A crappy clip either side.  We really mean it.  All right, do not turn that off.  Okay, reliability and performance.  So we've done...  What do we do?  We did standards compliance and we've done security.  So that's all the security stuff, okay?  Have I scared anyone enough yet that they're going to go back and change their code when  they get back to their workplace?  Come on, it's got to be worth my time.  I see some nods.  No one's putting their hands up, but people are nodding.  So moving their eyes up and down or looking away like this or looking like this for the  other people who have done it.  So good.  I got through to some people.  Okay, reliability and performance.  Whereas these two events, pre-send request headers and pre-send request content, anyone  using these, they're pretty rare.  Okay, someone put their hand up.  Okay.  Try to avoid them.  Registering for these events from within managed IHDB module.  So if you're using them from a native module, that's okay.  ISNative module.  Okay?  If you're using them from a.NET, ASP.NET, IHDB module, they have issues.  Okay?  So use the native ones instead.  I don't know what the issues are.  My runtime guy said, don't actually give me notes.  No, he didn't give me notes.  That's a shame.  But don't use them.  They cause issues with asynchronous requests, doing overlapping things and like sending headers  at the wrong time in the pipeline.  After headers have already been sent, it's possible to do it using the managed API.  The native API just solves all that for you.  So don't use them.  Even if you're not using them directly, you may be using a component that you bought or  downloaded that is.  So anyone here ever used a large file upload component for ASP.NET?  Anyone?  No one?  A couple of people hands, okay.  A lot of those use these events in the past, okay?  Because they want to do stuff just before they send a request back or as the request  is coming in.  So, okay, async page events.  So this is in web forms to do with the task-based asynchrony that we added in.NET 4.5, which  I spoke about here last year, I think, or the year before.  Try to avoid writing async void methods.  So you can do protected void, protected async void page underscore load and then write a  wait code inside your page load.  And that does work, okay?  Work for the simplest of scenarios.  But what we want you to do really, and same for button click handlers, you can do like  a protected void, async void, my button underscore on click, some async code.  And it kind of works, ish, in the really simple demo cases it works.  As soon as you do anything more complicated, you can introduce race conditions in your  code.  So what you should be using is the first class API for telling the page that there is going  to be async work.  And that is page.registerasync task, which has been around since.NET 2, okay?  It's been there forever, but we updated it in 4.5 to support task returning delegates,  asynchronous lambdas, okay?  You should be using that.  And what that does is it queues up the async work, when you call it from page init, page  load, button click handle or whatever it is.  And then once you get to pre-rendered complete, then it runs the async work in a coordinated  fashion.  And because that method that you registered with that method, you have to give it a delegate,  that must return a task.  We have an object that will tell us when that async work is finished.  Async void, we have no way of knowing when that async work is truly finished.  We can kind of track it using the synchronization context because it raises an event when async  work starts and then when it finishes.  But if async work kicks off more async work, that kicks off more async work, then that  can just all fall over, okay?  But if you use registerasync task, it just works.  And do make sure that you set HTTP runtime target framework equal to 4.5 if you're doing  any type of task async in web forms or in MVC or web API or signaler, okay?  If you're running on 4.5, make sure you set target framework equals 4.5.  That flips in the new synchronization context that we added in.NET 4.5.  It's opt-in.  We don't do it by default because it changes behavior of async work, okay?  So you need to turn that on if you're doing anything with tasks.  Now it's good on net.  If you do file a new project in Visual Studio 2012, it's turned on for you by default, okay?  Fire and forget work, try and avoid having code in ASP.NET where you handle a request,  so in an MVC action method or in a web forms page load or an Ajax handler or something.  Try and avoid kicking off fire and forget work.  Thread pool queues a work item, starting a timer that calls a delegate every so many  seconds from within ASP.NET.  The reason is at any point in time we may decide just to completely destroy the app  domain while that async work is running.  We generally won't do it while a request is running, but if you fire off fire and forget  work, by definition the request will be over very shortly afterwards and that work will  keep going, right?  Because it's fire and forget.  You don't care about it.  So if you do that, we can just tear down the app domain and you'll get all types of strange  exceptions in your background work and we may even corrupt your state.  And that can lead to really bad things.  Give you a writing software database in such a way or a text file and now we've corrupted  your text file.  Okay, because we just literally crashed your thread.  If you want to do background work in ASP.NET, first of all, don't.  Move it to a different process.  Write a Windows service or if you're in Azure, use a worker role, queue it and then have  some other process pick it up where you manage lifetime yourself.  If you absolutely must do it inside ASP.NET, you can check out web backgrounder.  It's a NuGet package that Phil Hack wrote that lets you schedule background work in ASP.NET,  work that happens on a background thread inside the ASP.NET app domain, but it listens for  the correct events.  So when the app domain gets torn down, we give it a chance to finish the work gracefully  before we destroy the world underneath it.  So look at web backgrounder if you need to do that type of work rather than just starting  timers in AppStart or doing thread pull.q as a work item, okay, use web backgrounder.  Okay, the request entity body.  Try to avoid reading request.form input stream before the handler.  This is pretty advanced stuff.  So if you're writing a handler and you want to be able to get the actual network stream  that represents the request coming in from the client because you want to do large file  upload.  You can do that like the stream as it comes in to do whatever it is, log it out or something  like that.  You shouldn't really do that before handler execute, okay?  You don't want to do that.  Or request.form, by the way.  You really want to try and defer it to when handler is executing.  Handle execute is the event where your action method in MVC runs or your page in web forms  runs like page.NET will fire, okay?  That's the handler.  The page or the MVC controller is the handler and handler execute will execute those things.  If you read request.form or input stream before that, either from a module, that's generally  where you'll do it from, from a module, then you can cause issues.  What you want to do instead is use these APIs here.  Get buffless input stream and get buffered input stream.  So get buffless input stream was added in 4.0 and get buffered input stream was added  in 4.5.  And they do what they say.  A buffless input stream gives you the raw stream from the request, which you call before  handler execute, but be warned.  If you call this API, you're telling ASP.NET, I am taking over this request completely.  I don't care what was going to run after me.  I am in charge of this request from now on, and I'm going to read from the stream manually,  which means things like request.form won't work because they usually get populated by  ASP.NET by reading the stream.  But if you start reading the stream, buffless input stream, then you read the stream.  You read the bytes into your own variable, which means no one else can read them.  It's a stream, right?  Once you read them, you can't look at them again.  It's not a buffered stream by default.  It's to literally a network stream.  So if you call this method, you can't call request.form.  You can't call request.files because that won't work.  If you call get buffered input stream, you can.  Get buffered input stream will give you the bytes as they come up, but it will also buffer  them away into memory or spool them to disk so that if later on in the request lifecycle  you do call request.form, it will still work because we took a copy of it before we gave  it to you.  Okay?  So low-level APIs, but we've seen issues reported where people had called these events and then  they called server crashes and types of things because they're doing things in the wrong order,  or they're doing things after certain things have happened or things like that.  Anyone actually using these?  Anyone actually used done input stream processing in ASP.net?  Okay, so that all fell in deaf ears.  Never mind.  If you ever need to do it, check out those.  Okay, response.redirect, and this is more of an be aware rather than a don't do this  or do something else.  If you call the overload of response.redirect, which just takes a string, that cancels the  request.  So when you call response.redirect string, the next line of code after that doesn't  run because we call response.end, which throws a thread abort exception synchronously inside  your code and literally tears your function call, your stack in half.  Okay?  You were calling this function, you were this point in the call, you called response.redirect,  and then we just canceled the thread by calling thread abort so we could return it.  Okay?  Which may or may not cause really odd things to happen in your application, depending on  what you were doing.  Okay?  So we call it a function type of state in memory and then we just kill it on the fly.  For async when it's handlers, response.end does not abort it, but code execution continues.  So the behavior that differs whether you're doing async programming or not.  In async programming, we change the behavior.  When you call response.redirect, sorry, when you call response.end in async programming,  it doesn't actually end.  We let the rest of the request run through and then we let it finish.  So basically don't recall response.end from an async handlers.  To end an async response, you have to return the task that you returned originally from  the async method that we showed in the signal I talked just before.  That's when the request will end, only when that task finishes or if you're using the  old pattern when the end method, when you call the callback that was passed into before,  into begin, sorry.  So response.end doesn't do anything in async.  If you want to redirect the response, you should be using the appropriate method given  to you by the framework you're using.  Now if you're using web forms, response.redirect is fine, but you just need to be aware of what's  going on.  There is an overload of response.redirect that takes a boolean, which you can say redirect,  but don't thread abort.  Redirect after you've finished executing the page.  In MVC, you'd return a redirect result.  Do not call response.redirect from inside your action method.  That is absolutely the wrong thing to do.  You need to return a redirect result from your action method.  And then the MVC pipeline will see that at the appropriate time in the lifetime of the  request and then send it back.  Now remember, this section is about performance and reliability.  We're not saying that this is going to cause issues immediately, but it does make your app  less reliable.  It may cause issues under load.  Having some of these things introduces certain race conditions or possible memory corruption  or stack corruption problems that you may not see until you get lots and lots of load  or you may see one in a million requests.  But they can be the hardest bugs to track down.  I'm sure you all have experiences of looking in the event log and seeing an obscure error  from ASP.  You have no idea why it was there.  You never saw it again.  You see it once every week and you don't know why it's there.  A lot of the time it's these type of things.  You may not be doing it.  You might be using some code, a component that you bought or something you downloaded  from the Internet that's doing it and you don't realize it.  Enable ViewState and ViewState mode.  Try to avoid enable ViewState.  Enable ViewState has always been there.  It's how you turn off ViewState.  It's on every control in the hierarchy and web forms, but when you turn it off, there's  no way to turn it on again underneath that control.  If you turn it off at the page, it's off.  You can't turn it on for one control.  ViewState mode, which we introduced in.NET 4, lets you do granular ViewState control.  You can set ViewState off at the page level, which we thoroughly recommend, by the way.  Just turn ViewState off by default.  Set ViewState mode equals to disabled at the page directive level.  At page, ViewState mode equals disabled.  That will set ViewState off for the page.  Then on the controls that your testing has determined need ViewState to work, turn it  back on just for that control.  That will save you an awful lot of ViewState that you otherwise would be taking up, which  is one of the biggest bugbears that people have with web forms.  It's really easy to fix in.NET 4.  Just turn it off and then turn it on for the controls that need it.  You'll see your ViewState shrink dramatically.  Has anyone doing this already?  People know about this already?  No?  One person?  Two people?  Good.  Okay.  SQL membership provider.  This is the inbox provider that we shipped forever for doing membership support in.NET,  using SQL Server.  We replaced this with an out-of-band component called the universal providers, system.web.provider.  It's a new get package.  It's used by default in the templates since, I think, Visual Studio 2010 Service Pack 1.  It's in all the templates in Visual Studio 2012.  It works with all databases that Entity Framework supports because it uses EF.  It doesn't talk to SQL directly.  It uses EF.  It'll work with SQL, Azure SQL, SQL Compact.  If you have the Oracle Entity Framework provider or the MySQL Entity Framework provider, it'll  work with those as well.  Just be mindful of that if you're still using SQL membership provider.  The other thing is that we made some improvements.  The universal providers have, they're better.  If you're still using SQL Server, these ones are better.  They don't use stored prox.  They're a bit more flexible.  They're faster.  They're better written.  We can update them out of band.  They're not in the framework.  They're on new get.  They're easier for us to improve as we go forward.  If you're deploying to Azure, you really need to use these ones.  Long running requests.  That is requests that run longer than 110 seconds.  Really, any request that runs longer than a couple of seconds is by definition a long  running request.  Requests generally should be over very, very quickly.  That's what we want our things to do, be quick as possible.  That's how HTTP was designed to work.  Some interesting things happen when you let your request run over 110 seconds.  By default, that's the request timeout setting.  Depending on what framework you're using, whether you're running a raw handler or web  forms or MVC, we may or may not just destroy the request and give you an exception, request  timeout exception.  Things like the session object.  Who's using session state in ASP.NET?  Be grudgingly.  Session state in ASP.NET is not my favorite feature.  I own ASP.NET as a feature-wise.  I don't like it.  Long running request.  Long running takes a lock on the session object.  When two requests from the same user come in at the same time, perhaps because your  page makes two Ajax requests or while the page is still loading, they hit a button which  makes an Ajax request, we block the second request while the first one is still active  because we've locked the session object for that user.  A lot of people have run into this when trying to do long polling in ASP.NET in the past.  After 110 seconds, we release the lock.  Maybe that's a bad time.  Maybe you were in the middle of doing some session work and now suddenly we release the  lock and all hell breaks loose.  Your session stuff that you were saving doesn't get saved.  Or the read that was going on suddenly happens when it should have been blocked.  So don't do it.  Don't try and have long running requests that are greater than 110 seconds that use session  state.  Just try not to use session state if you can avoid it.  Also don't perform blocking IO operations.  I think everyone's aware of what a blocking IO operation is now after two years of node  being on the scene.  We've talked about async a lot in the last two years.  We now have async APIs for all of the type of IO that you would want to do in.NET, whether  it's file, network, web service, socket or database as of EF6.  ADO.NET already supported it but EF6 supports it at the ORM level.  So you can do asynchronous OI now from web forms or from MVC or Web API signal and free  up that thread.  So for long running operations though in general, you better off to use web sockets  if you can or signal R. Just inject signal R anywhere web sockets is said.  As it has a much lower per request overhead.  The other thing a long running request will do is use memory.  Even if it's async, an async request that's long running won't use a thread when it's  idle but it still uses memory.  I mean there's still data stored in memory that represents that request.  But a web socket request in ASP.NET, special API introduced in.NET 4.5 is a much lower  per request memory overhead.  When you call accept web socket request and you give us the delegate, we unwind the request,  free up most of the memory to do with that request and then we invoke your delegate with  a restricted context, not the full HTTP context, just a small set so that we free up a lot  of memory.  It's about five times less than a full request.  Now signal R just does the right thing.  If you use signal R, we use web sockets when we can.  Otherwise we use long polling or forever frame or server center events and it's async so  we just try and do the best thing we can.  And that is the end of my talk with other people that I didn't do the talk with.  That's my boss, Cool School.  His name is Carl Scott Hunter, Cool CHR.  And you all know Scott Hansman.  So I have two minutes.  If anyone has any questions, I can answer them right now on stage or ping me on Twitter  and I'll do my best to answer them.  Otherwise thanks for coming along.  Any questions before I pack up?  No?  Okay, awesome.  Okay, awesome.  Okay, awesome.  Okay, awesome.  Okay, awesome.  Okay, awesome.  Okay, awesome.  Okay, awesome.  Okay, awesome.  Okay, awesome.  Okay, awesome.  Okay, awesome.
Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_0_131.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_132_227.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_228_611.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_612_2051.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_2052_3143.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_3144_4883.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_4884_9191.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_9192_10799.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_10800_12923.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_12924_13979.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_13980_14567.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_14568_15035.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_15036_15311.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_15312_17183.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_17184_17291.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_17292_17483.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_17484_18023.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_18024_18287.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_18288_20471.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_20472_28631.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_28632_31283.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_31284_31403.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_31404_31871.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_31872_32111.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_32112_32255.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_32256_32447.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_32448_33263.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_33264_35867.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_35868_36167.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_36168_36491.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_36492_37211.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_37212_43427.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_43428_44879.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_44880_44939.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_44940_45503.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_45504_47555.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_47556_48407.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_48408_49151.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_49152_49451.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_49452_49499.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_49500_50867.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_50868_51587.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_51588_52043.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_52044_52619.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_52620_52691.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_52692_63383.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_63384_68447.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_68448_68615.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_68616_69431.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_69432_72959.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_72960_77543.png Damian_Edwards_-_Don___t_do_that__do_this__Recommendations_from_the_ASP_77544_77645.png