 With Edgecase, Matt, I'll let you introduce yourself. Also with Edgecase, I'm Jim, the security assistant there. He's my hacker that I'm going to use in these demos. So we're going to talk about securing your real system. How many people here feel that the Rails application is 100% secure? An appropriate amount of laughter. I like that. It's not running. It's not running at this time. OK, I got really interested in security on Rails. Essentially last fall, when I read this article by Patrick McKenzie, he took a look at the diaspora source book base. Diaspora, if you're not familiar with it, is a Facebook replacement intended to support all kinds of your privacy concerns, to be very private. So he thought, let's look at it from a security standpoint. It was very interesting what he found out. He discovered that there were numerous security issues in the code base. And essentially, there was nothing that you could not do in someone's diaspora account. Absolutely nothing. In other words, it was totally open. It was very simple hacks. That made me start thinking. How secure is my Rails application? I've done it through all the normal security training that a lot of web developers get. How many people have hacked any security training at all? Let's reverse that. How many people have not had any security training? OK, now that's really interesting. It's kind of scary, too. Hackers don't think like we do. Now this is actually, I've got a program with a guy who's working on his master's thesis right now. And this program here, this is a recording live from last Tuesday. He is monitoring the power output or the power usage of a chip and presenting it with several keys. Since it takes more bits or more power to flip the bits, he can tell how close he is to getting the right password. He was in about 25 or 30 iterations. He deduces the 64-bit password. He isn't getting it yet. He's within one digit of it. Almost, almost. Yeah, I think he's got it there. I'll stop here in a second. Essentially, he figured out the password was the hex code deadbeath-dupeface. This is awesome. But he does it by monitoring the power bits on a chip. And this is actually a chip that you use to unlock your car. You know, a little remote on lockers. He could figure out the encryption code on that chip by monitoring the power of that. That's weird. Who thinks of things like that? I certainly don't. I'm pretty much a happy-path programmer. And I just assume that Rails works like it should. And it's certainly fairly secure. And this was kind of my little research about some of the things that go on. I'm a bit different than Jim in that regard, and I'm not. So I'm not a plain-to-be-security expert. So for those of us who don't necessarily have that as a background, there's a little bit of a greed in you when you can't have a Reddit. Obviously, in Rails guys, there are good stuff. But the pre-general security guys are particularly good. And it has a lot of really vital information about what were some of the built-in features of Rails that do protect our applications. And this is actually extracted from a larger document. I can't really pronounce children's name correctly. Hanko Weathers, I think, puts that. For O-Loss, which is the open web application security project that does things like monitoring the tops and exploits in the wild, and things like that. But it's a really short document, it's about 48 pages. If you haven't read it, definitely do so. He calls it recently short 48 pages. That's a long document to me. It's unbearable not to read it. So we're here to talk a little about the basics and what comes with the same stuff that's actually in the wild that I've been thinking about, that all applications are kind of going to be subject to. So to take for the sake of arguments, this is kind of a base, a very simple reputation of what web application architecture, straightforward web application looks like. Obviously, we have a browser. It was a web app server that's running our Rails code application we written. And we're likely not talking to the canvas. So for the purpose of this talk, we're talking about topics that deal with application security, we're not talking about system administration security, we're not talking about security server. But for the sake of argument here, of these three general sections, what sections can you sort of ask about? What can you trust? Yeah, yeah, yeah, all right, all right. Nothing's good against returnable people in the audience, I like that. Okay, but so can you trust the browser and of course you don't know, right? You can't trust the user input. And there's just database, no, there's no user input in the store, right? So we're looking various ways that common areas that issues that can come up that you can do either of those things. So let's talk about the very first basic thing that you will cover if you take any kind of security course. That's SQL injection. Supposedly I'm a query that looks like this. This is a very basic Rails query. We're using a conditions thing and we're looking for a name that matches that has some kind of filter task. And we want to make sure that we're not getting any admins in this list. So we want to just get a list of normal users whose username matches some kind of filter. And I want to point out this. This is bad. Anybody do this in a Rails code? Now of course in Rails it's made it very easy to not do this. So if you are still doing things like interpolating tasks directly into the conditions or any time you build SQL by hand, it's a danger of doing this. So be aware. Matt, why don't you demonstrate for us what could happen if you make that horrible, horrible mistake? Sure, so I'll show it real quick with a quick demo of that here. So we have just a simple app. We'll look at it a couple of times here, but it's scheduling moving items in front of you. For the purposes of that app, we've got a little screen here which shows some of the current users in the app that have access to C. They're basically permission-driven. And the simple filtering formula. So if I want to filter the users that I'm able to see. So I'll pull this case up with Jerry, I'm going to see Jerry's. And we can see here that we're going to say that we've got, it's injected into the query program on the screen, the query screen, this filter equal Jerry query program, which could indicate there's potential right there that maybe for a SQL injection So if I decide that maybe I want something that's a little bit more complex here, perhaps two conflicts around the other. So yeah, I'm going to drop that a little bit. I'm just going to say, oh. I think you need a quote. I think I need a quote. So I'm going to go to my, this is the smart phone. My live coding machine. There we go. There we go. Okay, so now it's going to see much more users than we had previously. The system. And I apologize if I'm just wrong. There are no admins in the system. I went through and took out all the admins. Oh, okay. So the previous time I was working, Chris showed us all the admins for the passwords, but unfortunately there were no admins. Yeah, it turns out that on SQL injection, you can inject any kind of SQL you want in the table. The more complex query that he called you would actually go to the table and print out the hashed password for all the administrators. So that's quite scary. So don't do this. Don't put the SQL injection, don't decircle it into your SQL. In the interest of time, I'm just going to do this really fast. This was a long, longer talk. I'm going to try and fit it down into your 30-minute time scan here in my road. There we go. And so essentially it means we inject extra code into the SQL statement just like that. The key to this is to use the question mark syntax in your conditions and let the rails stick that in and then we'll do a safety for you. You know, we'll quote things and shoot you, quote it. And the advantage of this is not only will this prevent SQL injections, it will allow names like O'Brien with an apostrophe to work correctly in your filter. Let's take everybody's seat and see what's going on. Call them little bobby taters. Let's talk a moment about mass assignment. Does we do mass assignment all the time in rails? Essentially it looks like this. You have a controller action, user update attributes and you just pass in whatever parameters are passed in on the HTTP call into your system. This is going to be problematic and would you like to demo this one? I think so. So I'll just go to here and I'll add in my profile and there's a couple of fields that I can update that I have access to and some of my data that I'm not able to change, I can change my name, I can change my email address, I can update that in system. But something else that I can apply a couple of things. You know, one, a minor degree of knowledge about how Rails systems works and Rails programming, the software works. And I could also employ the web developers, best friend of the web inspector. And I can go in and take a look directly at the DOM and I see that in this form that you have here that has two fields that there's one input for user email. And see that the format is user or private. Email and values is the previous value there. But I can actually go in here and edit this, edit the DOM directly and say take a wild stab in the dark and make there's an admin flag on this model. So if I say user admin instead and come down and change the value, we'll just say one. And we'll close that. And now if I go back here and update this record, you can see that now I'm not sure. Where'd you go? You know, I bet if I came up with a complex SQL injection tag, I'd be able to see in the password. But now if I click on the admin, it's the F. So now I'm in a conservative administrative system. Okay, the key to that one is by just simply editing the attributes in the Rails form, you can go in and attack any attribute in that field and change however you want to do. What you need to do is something like this. Make sure you mark what fields are accessible. Now there's two ways you can do this. You say these are the accessible fields which I'm allowed to change. Or you can say these are the protected fields from which I am not allowed to change. So it's essentially a whitelist versus blacklist approach. Do people use this? People set this up? Yes, very good, very good. So why are you here? Why aren't you trying to have dinner? Which is better, whitelist or blacklist? Whitelist. Why? Why is whitelist better? Denial. Denial, yeah. Whitelist says these are the things that are allowed. So it makes you think explicitly about everything that's allowed. A lot of people don't like this because when they add a new field, all of a sudden they can't edit it and they can't figure out why. That's because it's not going to whitelist. So they say, well, not the blacklist, the things that shouldn't be changed. The problem with that is that I feel it shouldn't be changed and all of a sudden people can change it because you forgot to add a blacklist. So it's a matter of convenience or security. You bet. Yes, question. What are you watching in? Subclass. Subclass is easier for admin. There's all kinds of things you do with a model to make it better. Yes, certainly. Yeah, I'd surely wouldn't use this in admin flag, but for simplicity and floor design, it's simple demonstrations. We actually had to work to make this app hackable, which actually is a good sign. Cross-site scripting is another interesting problem we're running to in actually in any Rails or any web application. And this is about a hack from both the browser side and the database side. The key is to get data into your database that you do not expect. I would just like to demo this one. Maybe. It sounds so popular. It's recently there, but no. So yeah, it's a movie, Night Creation, so I'm going to go ahead and schedule a night that I want to see an awesome movie with my friends. We're going to have it in the back gave that you should bring some beer and notes might be something like, maybe I want to have a goal, I could say, to put gold, you know, don't bring light beer in my notes and my friends right now. But I can also try something, you know, like, well, if I can get a bold hack, we're going to make it something else here. I really want to point out to them, you know, no light beer. And I try that and see if that's going to get a little bit too cross in the schedule tonight. Not make it look like it is. Okay, so technically we'll have it done there. I've embedded some JavaScript into a form that's going to re-explain to the page. Now remember, this is in the database now, so if anybody views this page, we'll execute this JavaScript. And that's, you know, okay, that's a neat point of the book. It seems relatively innocuous. Okay. But look, if I can do something slightly, slightly work-a-class with a little bit of luck, I'll try something else. And I will do a document.write through an image tab. And onto the image, onto the end of the URL, source afternoon to that image, I'm going to append a cookie back. Let's see what we get back. Now, if I schedule that night, let's see, well, it's an American image back, right? It's looking good and low, but what did happen? It moves all the time, right? It happens all the time. If you go back over to a server log, just a simple Rails app that I constructed here, you can see that a request came through, and it ends with that request included all of the cookie data, which in this case includes the session data, that is into some other random, delicious service web log, and that's obviously definitely a problem. Let's just think about that for a second. By just putting arbitrary JavaScript into the form, he was able to, to the user, like, well, there's just a bad image in this form and not think much about it. I mean, I see bad images tags all the time, but all that image tag he really did was go out to another server running somewhere else and send the cookie data before the session to that service. And the user never even saw it happen. He never was aware that that cookie data went out. And that cookie is the key to controlling your account on that application because he's got all the session information. Once he gets the session cookie, he can take over your account. So this all came from the fact that we wanted to display a lot of the user to put things like bold markup characters into that form. So to do this, we put raw right in here. This is a Rails 3 thing. So by default, Rails will sanitize all your HTML, which is good. That's a good thing that it does. But to bypass that, use the raw command. This is opposite from Rails 2, where you had to put the H in all your output to make sure it was sanitized. The problem is the raw. You don't want to be using raw if you can avoid it. And why would you want to? If you want to use a lot of markup, you might want to use something like textile or markdown which produces HTML. You want that to go through. Or maybe you just forgot to use the HTML Rails version. So solution number one, just don't do that. Don't use raw. But if you need to, in a lot of markup, use a white list of a loud markup that you don't want on that output page. Don't use a black list. Don't say what should be taken out, for example, if you have input like this, and you decide, well, we will just remove all these script commands from that user input, and then it will be safe, right? Unless the user does this. So if you've got bad markup, don't allow it. Don't try to correct it, just disallow it entirely. JavaScript can happen in places you have no idea where you would not normally expect it. For example, an href on an anchor tag, that's fairly common, but the background field on the table, you check all of those. The key here is, if you're going to be doing this, use the sanitize helper method in Rails. This is actually pretty good. If you're going to write a white list here, use the sanitize method in Rails. It is better written than what you can come up with yourself. Most likely. Static authentication for authorization. This is something I discovered that I do myself all the time in Rails program. Suppose you have this. You want to look up a night. So you say, okay, the night ID comes in on a parameter, and you just look up the night and you pass it out. The issue here is, you might not be allowed to see that particular night in the database. That might be a night that belongs to a user that you're not friends with, and he doesn't want to. It might be private. But we have nothing in here to protect it, and it comes right off the branch list, which is totally unprotected, that anybody could inject anything in that number right there. A better way to do this is to scope the query using the current user. So if you say, current user dot nights dot find, and then pass that in, you will not be able to find any nights that do not go along to the current user. Now, I've resisted using finders on associations. Mainly because I like to think of my objects as objects, and not think about them as database objects until the very last moment. So I tend to avoid this impact, because this makes it obvious the association is stored in a database. But because of this, I'm changing my query gathers to avoid the scope issue. More complex scenarios, just, you know, having the problem with scope finders because it's a basic fix, but you might have more complex opposition issues and that it might be more difficult to manage in this case of pulling in the plug and something like Ryan Bates can-can. There's a recent addition to that area. Who uses can-can? Yeah. All right, very good. I'll give you a more robust approach to proper authorization. This is an interesting one. Cross cyber quest forgery. How many people know what this is? You are an educated group here. I was kind of aware of how it was, and I knew that because of this, Rails was sticking funky things in my phone. But I wasn't quite really sure why they were sticking these funky things in, but consider this scenario. So there we have the hacker web page, and down here we have our movie night website. And you-you're currently logged into the movie site. And-but in a spad of inattention, you decide to browse the web a little bit and you find a link that takes you. It was hacker web page. And you download a page from that, embedded in that page is an image request. It says movienight.com slash night one destroy. The browser sees that as an image request and immediately sends that URL to movienight. What happens? There's no protection in place. Delete that night. This is cross-site request forgery. We're forging a request to the site from a different website. And it says, well, we should be restful. A get on an image should not cause things to be deleted from our database. So if we follow restful rules, we should be fine, right? It doesn't seem to be much more complicated than you had suspected. So this actually will do a post and will actually delete it as well. The key to this is that Rails will inject an authenticity token into your forms. And this token is something that Rails knows about. He records it so that when your forms come in and you make a request like this, that if you do not have the proper authenticity token in your form, Rails will say failure is not found or saying valid one and will deny the request. So that is the protection against cross-site request forgery. Now, you know why the funky authenticity token is in all your forms. You have to use the Rails helper to generate that because, you know, do that in the forms that you generated. You generate a form by hand to make sure you get that authenticity token in there somehow. The key thing to remember here that the authenticity token buys you nothing if you're a lot of cross-site scripting. Because a cross-site scripting attack can walk your page with JavaScript, find the authenticity token and still submit it. This is a real danger. There are sites that have lost great deals of money because of attacks like this. There was a credit card thing in Mexico where they actually embedded some stuff in the routers. The routers would download things. They were able to program the routers through attacks like this and redirect the DNS things from the Mexican banks to their own websites. You can imagine the problems that would cause. Would you like to talk about session spoofing? I would like to talk about session spoofing because the next image is pretty awesome. We don't remember what was the fire sheep going around, right? This was a nifty utility that you can install as a browser plugin to let you kind of view the active, ongoing sessions versus your audio and popular social media sites like Facebook and Twitter and things like that. I'm not going to do a demo of that right now. And you can thank them for that. Those of you who are a long way from the public Wi-Fi right now. Thank you. But that's obviously a very serious issue. And thankfully, the intent was to generously look at the session on the topic because it's a known exploit that session spoofing has been known for quite some time. But in the aftermath of that, you start talking about what you've done. That one requires a sell. Like in this day and age, you know, 2011, you know, requiring a sell by default for any authenticated sessions is a pretty choice, right? It's the way to go. Part of that, you also need to make sure you use the secure cookies. So cookies, you know, obviously cookies that are a secure session often your session token, for example, is going to need to be protected. But even if you're doing a redirect, so if someone goes to log into your site, or goes to, I believe, to sell to your site over HTTP, and you re-grap in the HTTPS, well, they're all hardly going to have transmitted their cookies. So we're going to be clear on that first dimension to a private redirect, unless the cookies have been supposedly marked as secure, a new version, a potential standard right now is the strict transport security. There's a link to the IETF documents. Here they'll be in the slides. Basically, it's a new server header, which the server can instruct a browser that it must phone communications over a sell TLS. How can you bring that to your apps right now? Rack SSL is a Rack Middleware room by Josh Keith that basically will enforce these requirements because require SSL will mark all cookies to secure it on that. They will send that to the header down for all requests. So just having this a couple of days ago, I'm sure a lot of people probably wouldn't notice it, but Twitter is out of an option that you can configure to strict, by your account, that you only go over SSL. Always use HTTPS. And that's a great thing. Obviously, now, Twitter is one of the services that would sort of, you know, exploit it on that. It would be great to see, you know, to cross the next step, to do away with it being an option, right? Because currently it's off of the call. Gmail, Google Web Services did this in the past. So if you were back, there was a point now where you could choose to restrict your Gmail account to SSL. Now, it's always SSL. So hopefully, that would be great to Twitter as well. Okay, let's talk this summer really quick here. We have 44 summers left for this summer, right? Trust nothing. Stay up to date on the security patches. This is a big thing. It only picks as security holds that they find. So stay up to date on that. You'll be much better off. A lot of the hacks and demos that we did today, we had to explicitly bypass the defaults that Rails built in for us. We had to bypass for all. We had to use special things to be able to access the cookie from JavaScript. Rails, by default, is doing actually a fairly decent job. Your job is to make sure you don't pull the bonehead moves up interpolating into SQL queries that always scope your finds by the proper privileges. Avoid using RAW or at least sanitize your HTML. Do a security audit. How many people have done a security audit on their code? We've done a couple on some of ours and it was very interesting to obtain that. I highly, highly recommend finding a good security firm that knows what they're doing and have your code audited. Just be aware. Think like a hacker. They don't think like you. Think of the corner cases and consider that when you're building your web app that you don't automatically build things in. Thank you very much.