 OK, folks, so it's 12 o'clock. This is going to be Graham Sutherland, minimal effort web application security, aka how to make my job harder. If everyone can give him a bit of support, a round of applause, that'd be fantastic. Thank you, Graham. Hello. I feel like I should explain the outfit. So we have corporate slides, which I hate. The slide templates, I really don't like them. So my forfeit is I have to wear a corporate banner. So I have my robe and my wizard hat. So yeah, I'm Graham Sutherland, and I'm going to talk to you about really low effort tips for being lazy developers, because I used to be a developer and I was lazy. So yeah, my name's Graham. I'm on Twitter. Follow me, tweet me, whatever. I don't care. I'm a pen tester for Port Gollis Computer Security. They're nice people, they sent me here. There's a few of them over there. They might not be quite as nice. Yeah, I'm normally into Windows Internals, binary applications, cryptography, embedded systems and hardware, doing a bit of tinkering in the hardware space, and generally anything that's kind of fun and onage. Oh yeah, we're in 10c1 if you want to come and talk to us and say hi. We're also doing a USB scavenger hunt. It might be a bit late in the day to get started, but it's still fun. So yeah, come and say hi. Oh yeah, this was the slide that I put up to remind me to explain the outfit. Yeah. So yeah, corporate slide, which is always mandatory. Yeah, we're a security company based in Watford. We've actually just moved office. We were in a little barn before. Now we're in a big, shiny office. It's actually a pretty awesome place to work. So if you're into security and kind of want to look into moving to pen testing, we are hiring. So yeah, we have a beer fridge and pool table in PS4 and improbably sized TV. So it's kind of a nice place to work. And they sent me here as well, so. Oh yeah, there's a lack of warranty. You probably can't read all of that. It's kind of silly, but just a heads up. There may be some weird little images in here that are not safe for work, not safe for children, or not safe for life. Don't worry, they're not too bad. So yeah, normally I do talks on how to break things or these are the things that I broke. But I decided to do something kind of the opposite side of the field this time. So instead of saying, OK, this is how you can break stuff, how about make stuff that's hard for me to break? So ruin my job security in the long term. So why should you care about security? So there's a lot of people who would say, I don't know, oh, we're not big enough to be targeted. Nobody will care enough to hack us. No gain from hacking us? Oh, what have we got on our site? There's nothing sensitive. Or it's not my responsibility. I'm just the dev. We've got security guys for doing this. Well, it turns out that none of those things are true. So I'm not big enough to be targeted. Well, it doesn't matter. There's so much automated malware out there. So I saw a great video the other day of a guy put an unpatched Windows XP installation onto a laptop, plugged it into the internet, no nap, and it was owned by the time he logged in. So yeah, basically there's so much automated malware out there, just hammering out generic exploits that if you screw something up, then it's probably not going to be long until you get hit and you get a big headache trying to fix it. Again, nobody will care enough, well, if there's automated stuff around. Or just people doing it for the rules, like oh, that's a weird website. Let's own that. Google docking, the usual stuff like that. No gain from hacking us? Well, you've got a server. Servers are usually on reasonably decent internet lines. You may just become a DDoS node or just end up in a botnet. We don't have anything sensitive. Again, it doesn't really matter. People are still going to just use your hardware. Or not my responsibility. Well, the thing is, as a developer, it kind of is your responsibility to get the code right. Because even if your infrastructure team builds some awesome infrastructure, sticks up with firewalls, web application firewalls, intrusion detection systems, intrusion prevention systems, if you've got a logical flaw that says, OK, if I go to such and such a page, I can read somebody else's PMs. Well, none of that infrastructure, none of your AV, your firewall, your intrusion prevention is going to stop that. You've got to build security into your applications. And it's not that hard. Once you actually understand the few little tricks that you can do, it's not that hard to build them in. Especially if you're building a web application from the ground up and not trying to patch security in later. So the later you try and put security in, the harder it's going to be. Oh yeah, I found lots of silly stock images on the net for quite a few of my slides just by putting in a keyword. I quite like that one. Yeah, this guy is not your attacker. So as I was saying, I don't know if you can see it. It's a guy in a balaclava. I love it when Hollywood does that. Because I love the idea that I would be sat at work in a balaclava. Just, haha, I'm typing my report. In reality, it's just malware. It's going to be malware. It's going to be idiots sat at home going, huh, I'm going to break into your site and deface it. Leet Hacksaw was here and all this shit. In general, you're not looking at what the industry calls advanced persistent threats, which is just a marketing term. Basically, it means people who actually just want to break into you specifically. But in general, you're just going to be looking at your average day-to-day just board kid wants to break into things. So there is kind of a reasonably sized toolkit for when we're breaking web applications. But the main thing that we use is a piece of software called Burp Proxy or Burp Suite. It's basically, you point your browser to it and then you view a page through it and it does a bunch of funky stuff like you can mess with traffic as it's coming in and out, send messed up requests. And it also has active scanning features and things like that to spot obvious vulnerabilities. It's really useful when you're developing because you'll spot things way ahead of time. We use this for our web application testing all the time. Pretty much if there was only one tool that I was ever gonna use again for a pen test, it would probably be Burp. And there is a free version, so yay. Not advertising them, they're just useful. Oh yeah, Burp. So, vulnerability types, there's a lot. You have to contend with a lot. But the interesting thing about this giant ridiculous list is that about four or five of these items account for about 80% of exploited vulnerabilities in the wild. So for example, SQL injection and cross-site scripting is just a massive area of the market, it takes up so much of it. When we're getting down into deserialization bugs and session token leakage and stuff, they're a lot more rare or obscure and not as easy to spot or exploit. Well, sometimes. But in general, the majority of bugs you're going to find on the net are going to be from just a very small number of these categories, rather than all across the entire range. So for the sake of sanity, I'm not going to try and cover all of those. So we're just going to look at injection, so SQL injection. I'll explain it a little bit. Cross-site scripting, cross-site request forgery, click jacking, bad password storage, which is a favorite of mine, and SSL downgrades, because that's just a nice quick little one at the end. I searched for the word attack on Google Images and found that weird, creepy image. I don't know if you can see it very well. Yeah, it kind of freaked me out a little bit. So injection, SQL injection. So how many, show of hands, how many of you are familiar with SQL injection and sort of how it works? How many of you aren't? Right. Tim, did you just put your hand up? Right, okay. So I'll very quickly go over it. SQL injection is, so SQL database language, you select a bunch of stuff from a table, blah, blah, blah, do some processing on it, return the results. If you take a parameter into that query and you don't appropriately separate it as data or sanitize it in some way, then it may be possible for somebody to insert commands into that query, such that the result comes back in a different way. So for example, if you did select name from users where ID equals, and then you take an ID from, say, a get parameter in a page, if somebody puts one union select password from users, it will dump all of your passwords out of your user database. So yeah, that's a bad idea. So escaping, so many of you probably know the kind of the default answer that a lot of, like for example, W3 schools, which I hate, because they lie to you about security and tell you to do things wrong. A lot of people will tell you to escape things. So for example, MySQL escape underscore string, that's a bad idea, don't use that. There are so many ways in which you can use that and get it wrong or you can miss one parameter and you're totally screwed. It's a bad idea. The better way to do it is just go from the ground up with parameterized queries. Now, I see people online suggesting parameterized queries and they're not really qualifying it in any way. Parameterized queries literally separate the data from the query. You cannot inject through a parameterized query if you do it right and it's quite hard to do it wrong once you get into the pattern of it. And the great thing is that most libraries now, so I mean even PHP has MySQL I or PDO, .NET is all like entity framework. Pretty much every language has parameterized queries now. Most of the old like string concatenation style stuff is now considered deprecated. So if you actually use a modern library and you actually look into, okay, I wanna do kind of querying in the modern world, you're gonna see that it's quite hard to avoid parameters and they become very useful. And once you get into that habit, you find yourself almost struggling to think of a way that you might have introduced a bug because if you do it right, if you're using your parameters everywhere, there's no reason that you should introduce SQL injection bugs. Unfortunately, it's not effort free if you're building an application, sorry, if you're trying to take an application that used concatenation style and move it over to parameterized queries. That's a bit of a pain, but if you're writing something new from the ground up, definitely look into using parameterized queries. Yeah, another ridiculous stock image I found on the net. Cross-site scripting. Cross-site scripting is fun. Almost every single piece of example code on the net that I've seen for sort of learn to use this web language will be vulnerable to cross-site scripting immediately because they don't tell you about it straight away. Cross-site scripting is essentially, if I give you some parameter to your page and then you print that back out into your HTML output and then I go and put some script tags in there, can I execute code in your page? Probably, because you didn't escape it. So if you don't escape it, then my code's gonna run. Now, what can my code do? Well, how do you maintain persistence in a web application for user session cookie? Can my JavaScript read your session cookie? Maybe, if it can. Can it send it back to me? Maybe. So if I get your session cookie back, what can I do? Well, I can take over your account and I can take over your session and I can do evil things. So cross-site scripting is kind of nasty. It's a huge portion of the market in terms of spotting vulnerabilities out there in the wild. They're often quite trivial to exploit, some of them are quite difficult, but it's found in roughly half of web applications, which is quite scary and quite great for me because it means I'm always gonna have a job unless you start fixing things. So yeah, the usual attack stealing cookies. If you can't steal the cookies, cross-site request forgery tokens, I'm gonna go on to cross-site request forgery in a minute, but basically, if I can't steal the cookies, if I can steal the cross-site request forgery tokens, I can probably do just as bad stuff. But there are numerous fixes and mitigations for XSS. So the main one is gonna be, well, hang on. Oh yeah, this one's great, I love this. This is a Visit Spain website, an official government website. Somebody found cross-site scripting and injected Mr. Bean's face into the website. I love it, it's amazing. Yeah, so obviously, again, escaping your output is the major way to prevent XSS. So there are libraries out there to do that in terms of saying, okay, I wanna output this to the page, but the user gave me this, so I don't trust it. So I need to escape it so that it's put into HTML entities so that like triangle brackets aren't actually just output as triangle brackets, they're output as entities, so they're encoded. But just in case you do let an XSS vulnerability slip through, there are a bunch of ways you can mitigate the impact of them. So one of them is, so this top one, this top header, I don't know if you can see it, XSS protection. It's an Internet Explorer-specific one which enables what's called reflective cross-site scripting filters. It means that when a user visits your site, it forces the XSS protection on so that you can, so that users are protected against somebody sending them a dodgy link that contains some cross-site scripting in there and IE will recognize it and go, oh no, not loading that, warning somebody's trying to mess with you. So it's a nice little trick, unfortunately, IE only. Other browsers just have that by default. It's just a nice little header to include to cover the ancient people who still use IE. Second one is X-content type options setting that to no sniff. There are some funky things that people do with character encoding, like UTF-7, to try and get around XSS filters. Setting no sniff on helps the browser just go, okay, I'm not gonna try and guess the type of the encoding type of the page, I'm just gonna assume a default. That's a nice little mitigation against certain filter bypass attacks, it's quite nice. Content security policy is one of my favorite things in terms of web application security. I'll warn you ahead of time, it is almost impossible to implement on an existing site. If you're building something from the ground up, it's not too difficult at all. It's when you actually start thinking about how CSP works and implementing it into your application, it works quite well. What it does is it sets a bunch of restrictions on where you can load certain things from. So the default blanket thing it says there is no inline CSS or JavaScript in your pages at all. So you can't have script tags in there that contain JavaScript inside the page, you can't have CSS in there, you can't put like onload on attributes, you can't do things like inline styling. Instead, everything has to be separated out to an external file. And what CSP does is it says, okay, you can only load JavaScript files, CSS files, images or anything else like that from these locations. And it can do this for flash, it can do, well, just general objects, it can do it for fonts, it can do it for JavaScript, CSS, live frames. Basically, it's a great way of locking down where you can load things from. It's also really nice to stop, the secondary protection it has is that even if somebody says, okay, all right, I can't inject JavaScript into here and steal somebody's cookies, but I could make the company or the person look like an idiot by injecting all this horrible stuff in there and making their website look silly. Well, because you can use it to prevent resources being loaded from non-trusted third parties. So you can say, for example, only load this from this current domain. So you can't load anything outside of the current domain. So I can't load it, if I'm on blar.com, you can't load anything from food.com. It's a great little mitigation that's useful for more than just cross-site scripting. It's very useful, so I definitely recommend you take a look at that if you're building web applications from the ground up. And finally, the cookie flag HTTP only. When you set a cookie, you can actually set this flag HTTP only. What that does is it says, don't allow scripts to read this. So only the browser will send that cookie over to the server as part of the request, but the JavaScript on the client side cannot read the cookie. That helps prevent cross-site scripting from stealing session cookies. Cross-site request forgery, pretending to be other people. So when you're logged into an application, you're clicking on things, you're making requests, your browser is sending your session ID so that the server knows who you are, knows that you're logged in as you. Well, what if I got you to click on a link which then took you to a page that says, I don't know, delete all of my messages. So if I send you blahblahblah.com slash delete all and you click on that link, maybe through like a link shortener so you can't see what it is, you click on that and bam, you've lost all your posts. This is called a cross-site request forgery. What it means is you are giving somebody a link or sending somebody to a malicious page that therefore, that then causes, oh, there's a spider on my mic, sorry. Slightly distracted there, it's a bit weird. Yes, that then causes an action to be executed on your behalf. So it might be, for example, reset your password to a particular value so that then they can take over your account or it could just be, I don't know, issue me a refund of a thousand pounds. It'd be quite nice, wouldn't it? So the way to get around this is usually using something called cross-site request forgery tokens. So there's a double submit model which is quite commonly used. So there's two ways to do it. There's either the essential gist of the way it works is you randomly pick a token. You put that in your form data so that when you click on the form, it sends that token through. When you legitimately click on, delete all my posts, it would send this token through. And that token is also stored in either a cookie or it's stored in your session data. Have I just got that wrong? Are you sure I got that wrong? I got it right, yeah, sorry. I had a bit of a brain fart there. Yeah, so the idea is that if they don't match, then it doesn't do the request. Yes, I am right. So because an attacker can't read your cookies or shouldn't be able to read your cookies, they can't tell what that value's gonna be. Or if you store it in the session data, there's no way they could ever read it because it's on the server side. So as long as they can't guess the session token, sorry, as long as they can't guess the cross-site request forgery token, that prevents them from just sending you a link, you click on it and bang, because they don't know that token, they can't verify it. So if they match, accept the request. If they don't match, time to bugger off. And there's token. Clickjacking, like clickjacking, it's weird. So clickjacking is a clever little trick. It's also known, well, it kind of falls into a second category called UI redressing. What it is, is imagine you've built a web application, you've built a website, and I take your website and I embed it in an iframe, in my page. But I make the iframe exactly the same size as my window, remove the borders, so you can't tell that you're browsing on my site. It looks like you're browsing on your site. Now, there's a thing called same origin policy, which doesn't allow me to read things that are inside that iframe. My outer page can't read anything in a page. That's a security feature in pretty much all modern browsers. However, there's nothing to stop me from then putting a UI element, for example, a div or a span, positioning it absolutely over the top of the iframe, so it looks like it's part of your page. So it says, please enter your username and password. And I've put my username and password form right over the top of yours. And they type it in and it goes straight onto my site and I get their username and password. And then it says, oh, it just like refreshes the page back to the real facebook.com or whatever, and I've stolen your password. The alternative way of doing that is that there's a secondary way of doing that, which is if you're already logged into an application, then somebody could load up the page that says, oh, are you sure you want to delete all of your posts? And then what they do is they put a big banner over the top of it and saying, you know, oh, I don't know, click here to win a free iPad. And then you click here, and what they do is they have a bit of JavaScript on there as just as you click on it, it disappears. And then you click the button underneath and then bang, you've just deleted all your posts. Awesome little trick. There's a way around it. So you can set what's called X-Frame options, it's a header in the response of your web application when you reply with an X-Frame options of deny, your browser will never let your website be embedded in an iframe. So if you don't use iframes, you can just use X-Frame options deny and no iframes will ever be allowed. X-Frame options, same origin, allows for iframes, but only when the outer page is on the same domain as the inner page. So that means that if you are actually using iframes in your application, you can still do so. It stops third parties from embedding your entire site back over it again. So it's complete protection, asterisk. The asterisk being that there's never a 100%, there are still always little tricks and things like that. And again, it's nothing more than a config change just like some of the previous things I've mentioned, just setting a header in like, for example, your Apache config or your nginx config. Password storage, this is my favorite picture of the entire. I wanted to get a picture of Jamie Heineman and I Googled for it and saw that picture and I just couldn't resist. It's brilliant and hence the not-safe for life tag. Let me dispel some myths about password storage. Who here has been told to use salted SHA-1 for their passwords, raise of hands at some point? It's all right, you can put your hands up and it's fine. Yeah, or MD5 or anything like that. Yeah, you were lied to. That's the advice that I would have given if it was 1993. Basically, so there was a bit of history around it, in fact. Yeah, so here's some history and it's not about aliens. So back in the day, people stored passwords in plain text. I'll be quick. People stored passwords in plain text and what happened was people got their databases popped and then people stole the passwords. So then what they did was start hashing them with cryptographic hash functions, MD5, and then someone went, oh, but what if we take all the common passwords and then do an MD5 of them and store that in a big database and then we can look it up. When we dump the database, we just get the hash and then look it up in the database and then we find the plain text. All right, so we'll salt it with a random value so that it's really hard to just build these databases. All right, well, we'll just crack them. So we start cracking them with various bits of tools, John the Ripper or a hash cap. And then people start going, okay, MD5, oh no, it's too quick, we'll get something slow, we'll use char one, it's more secure, but it turns out char one's basically as fast. So for example, GPU based crackers can now crack somewhere in the region of about 45 billion hashes per second. So you can kind of see how that can get quite scary. So you can get people, people have built rigs with like seven top end GPUs and just done password cracking on them and they can get through a lot at once. So now what we recommend is slow algorithms. So for example, PBKDF2 or Bcrypt, what these do is they take a cost function, so cost value, so like between one and 30 and the bigger the cost value, the longer it takes to do it. So if it takes 0.5 seconds on your hardware to hash a password, then how is an attacker gonna do a billions of them a second even on GPU? Even if it takes 0.1 seconds, it's still a lot shorter than the nano seconds it takes to do a char one hash. Scrypt is a variant of this that's also what's called memory hard. It takes advantage of the fact that if you wanna crack passwords in A6, you don't have a lot of local memory, so it requires a large state which slows down the operations. Finally, I'm gonna go quite quick because I know I've only got a couple of minutes left. SSL stripping, people can attack SSL by when you go to a website you type in HTTP colon four slash four slash and then blah blah blah blah blah and it says, oh no, we want you on SSL and forward you over to SSL. There are tools like SSL strip and MITM proxy that can get in the way and basically man in the middle of that traffic and strip out that redirect and then basically act as a middleman or they can pretend to be the host with a fake certificate and then talk back to you and you go, oh, what's this warning? I don't care, click yes and then they're just stolen all your data. So you can get around that by, oh, yes, evil. Yeah, you can get around that by A, setting the cookie secure flag which forces cookies only to be sent over secure connections, which means that if somebody downgrades you to HTTP they don't get your session cookie and you can set a header, HTTP straight to transport security. What that does is the first time you see that header it says, okay, don't accept a non-SSL connection here for the next X amount of time. So when you come back to the website, if you type in HTTP, kind of a four slash four slash, your browser goes, oh, I have a HTTPS rule for that. Switches over to HTTPS and never accept a HTTPS connection back. So it's a nice little trick around that. Again, it's just a config that you can change in your HTTPS server config. So yes, it's hardened. Some quick generic tips. Mod security in Apache. It's just a module you can load in. It's got a whole bunch of nice little functions in there that can help increase your web application security. So I'm gonna have to go really quick here. Disable any modules you don't need. Turn off the X powered by header in PHP because that tells them exactly what version of PHP you're running. So they can go and look up a bunch of exploits for your version. Read some hardening guides for any web applications that you're using. For example, WordPress or Joomla. Avoid third party plugins for WordPress or Joomla because generally they tend to be really, really bad and full of SQL injection and XSS and horrible things. Unless they've been vetted and you can see people have done security analysis on them, I would avoid them. Have no plain text management stuff on your web servers. FTP and Telnet is just horrendous. If you sat around here going, oh, I'll just go and update my server over Telnet. And people are just sniffing the traffic around and stealing all your passwords. And don't put your keys on GitHub. There's a bit of an in-joke here. The badges that were used have ECC to do the authenticity on the outbound messages and then they left the ECC private key on GitHub. And then unfortunately they changed it so I couldn't mess with it, but oh well. And the conclusion. So there's plenty of attack types, but entire classes of them can be prevented relatively easily. Many fixes are just configuration changes and knowing these things is half the battle to doing it. Yeah, end of presentation. Thank you very much. No time for questions. Okay, so we've got a little bit of time for maybe one or two questions. Any burning questions? I'm gonna take this off, this is really hot. Anything? Take it on. It's too hot. Jesus. Nothing? Okay, well let's just give Graham another big thank you. Thanks, Graham. Oh, just a quick reminder with the USB hunt challenge thing that we're doing. Somebody seems to have taken challenge five and wondered, did we replace it? Right, it's been replaced. Somebody took challenge five and then wandered off with it. If you are partaking, please leave the USB sticks where they are, just copy the data off them and then carry on. Oh yeah, if you get past five, definitely let us know because that one's evil and we wanna know how you did it. All right.