Cross-Site Scripting (XSS)
Summarized using AI

Securing Your Rails App

by Jim Weirich and Matt Yoho

Video Summary: Securing Your Rails App

The video "Securing Your Rails App" focuses on the importance of web application security, particularly in Ruby on Rails applications. In the talk presented by Jim Weirich and Matt Yoho at LA RubyConf 2011, they highlight the common vulnerabilities that can lead to security breaches if not properly addressed.

Key Points Discussed:

  • Understanding Security Risks: The presenters emphasize that no web application can be deemed 100% secure without diligent attention to security practices. They cite an alarming example from the Diaspora project, revealing severe security flaws that could allow hackers complete control over accounts.

  • Common Vulnerabilities: They identify and demonstrate several key vulnerabilities:

    • SQL Injection: A short demo showcases how easily a hacker can manipulate input fields, exploiting improper SQL statements to access sensitive database information.
    • Data Manipulation: The presenters illustrate how users can change critical fields, such as admin flags, by manipulating form submissions.
    • Cross-Site Scripting (XSS): They stress the risks associated with displaying unsanitized data, leading to potential attacks through malicious scripts.
    • Cross-Site Request Forgery (CSRF): The need for implementing authenticity tokens to prevent unauthorized actions on behalf of authenticated users is highlighted.
  • Best Practices for Defense: The speakers recommend several strategies to mitigate these vulnerabilities:

    • Validate and Sanitize Input: Always treat incoming data with scrutiny and sanitize any output to avoid security slips.
    • Use Parameterized Queries: Instead of interpolating SQL commands, utilize prepared statements with parameterized queries to prevent SQL injection attacks.
    • Modify Permissions Carefully: Use Rails' 'attraccessible' or 'attrprotected' to manage which attributes can be modified through forms, ensuring sensitive data remains shielded.
  • Resources for Further Reading: They encourage viewers to read the Rails Security Guide and OWASP guidelines, which provide comprehensive information on securing Rails applications.

Conclusions and Takeaways:

  • Security requires constant attention and should be integrated into the development process from the start. Trust no incoming data blindly and always conduct thorough validations.
  • Developers must cultivate an awareness of evolving security threats and utilize proactive measures to safeguard their applications against potential attacks.
  • The video serves as a call to action for developers to prioritize security and continuously educate themselves about the best practices to protect their web applications.
00:00:29.800 Hi! How are you guys doing today? Great! Are you here to learn about Rails security?
00:00:34.960 How many people are absolutely certain their Rails application is 100% secure? Yes, Rich? I believe you. Anyone else?
00:00:43.680 Not? Uh, this is us! We got a great introduction, so we'll just skip that. I started thinking about security seriously this past fall when I ran into an article by Patrick McKen.
00:00:49.239 He was writing about the Diaspora code base, which is an open-source Facebook replacement that respects your privacy. That code just went out on alpha release.
00:01:08.159 He checked it out, thought he would look it over, and was surprised to find several severe security errors. In summary, he said that the bottom line is: there is nothing that you cannot do to someone's Diaspora account—absolutely nothing.
00:01:16.040 In other words, the site is entirely hackable! You could take over anybody's account quite easily. I don't know if that scared me because I'm thinking, 'Well, I do Rails development', and you know what I know the basics of security.
00:01:28.280 I've gone through all the security lessons and I know all that stuff, and it was scary to me—it bothered me a lot.
00:01:35.840 Let me just give you an example. This is some code that we were playing around with back at EdgeCase. We did the Ruby Coin project, and someone had the great idea to put the coin online.
00:01:43.600 You can actually go through the coin on a web page, and you can see these tests. We're asserting equality. You can fill these things out, and when you fill them out with the right thing, the test turns green.
00:01:55.039 Well, we're actually typing in Ruby code at that point and evaluating it in the browser. Yes, you're laughing already; you know what's coming, right?
00:02:06.680 Within two minutes of the guy who did this, he published it in our Campfire room. Within two minutes of that, someone typed, 'The answers which you seek are...' and this is the Etsy password file.
00:02:22.680 What he did was type in 'system cat /etc/passwd' into the text box there. Well, he thought, 'Ha! That's clever!'
00:02:32.120 I'll fix you guys! I'll just disable the system command. So we switched to using backticks. Okay, okay smart guys! We'll just disable backticks. At this point, he decided, 'Alright, I need a real sandbox to put this stuff in.'
00:02:52.120 And actually, we're working on putting this online for real right now, and it's in a real sandbox. Theoretically, you're not going to be able to break into it once we actually release it, but we're still playing around with these ideas.
00:03:06.560 But the question is, you know, while we were playing around with this, we knew it wasn't secure—it was an internal thing and we were just having fun with it. But in real life, what are the security concerns?
00:03:16.680 Just two, maybe three days ago, I saw this post from Martin Fowler. Did anybody see this? This was on ThoughtWorks.com. If these guys don't know what they're doing, what hope is there for the rest of us? Evidently, they have some malware on their website.
00:03:34.600 It's transient; they can't track it down. It shows up sometimes in their Google reports, sometimes not. They're not quite sure where it is. It might even be a problem with their Pion; we don't know for sure. They are tracking this down now; they have suspicions, and they think they've tracked it down, and they're working at it.
00:03:57.280 If you see anything suspicious, let them know. But this is a tough problem to solve, absolutely. We've used five minutes now of our 30-minute talk. We are not going to be able to cover anywhere near all the security concerns that you have to think about when you're doing a website in the next 30 minutes—absolutely no way.
00:04:10.120 First of all, I want to say I am not a security expert. I did not study these things in depth. These are just things I got interested in when I saw that posting. I thought it would be a good idea to share with you some of the basics you should be doing. After this talk, every one of you should go and read the Rails security guide. This is really comprehensive and really good; they cover things specifically related to Rails.
00:04:51.759 Another resource you can Google for is the Ruby on Rails security guide at rubyonrails.org/security.html—that's easy to find. The other resource is the OWASP Ruby on Rails security write-up. This is a PDF—it's a whopping 48 pages of stuff that you need to know if you're doing a public website. I'll say, if you're doing an internal website, there are vulnerabilities in those as well, and this is a good guide to point that out.
00:05:19.919 So that's your reading assignment after you get done here. But now for the fun part! This is your typical setup for a Rails application: you've got your server, your browser, and your database. Out of these components, which of them do you trust?
00:05:39.760 The browser, obviously not. The browser is entirely out of your control. Anything coming in from the browser is suspect. You need to validate it, check it for bad things, and you need to treat that data with the utmost respect. That includes not only data and forms but also cookie values and URLs. Do not put critical data in URLs because they can be easily hacked.
00:06:03.080 All of this stuff can be easily hacked, and we are going to demo that today for you. What else shouldn't you trust? Well, the database! You may think you have complete control of that database, but it's quite easy for a hacker to slip in data past your application.
00:06:18.319 Just because it's in a database you control doesn't mean that it's good data and it's safe to display however you want to. Cross-site scripting attacks often come from storing stuff in the database that is later displayed to other users. So out of these components, maybe you can trust the Rails server because that's where your code is running. If you can't trust your code, you probably have bigger security issues that we want to talk about right here.
00:06:46.320 In particular, the browser and database are the things you need to be concerned with, so we're going to start with the basic vulnerability. I call this the 'little Bobby Tables' vulnerability. We have an application that Matt and Jerry at EdgeCase did—it's a very nice movie night reservation app.
00:07:03.240 You want to watch a movie, you send invites to some friends and tell them about the movies you're going to watch. We played around with this application and have now let me preface this—all the vulnerabilities we're going to display today were not in his original code.
00:07:18.120 We had to either change the code base or disable features in Rails for us to actually demonstrate this. So that is the good news in all of this—that Rails is actually doing a very good job of implementing security, but you need to be aware of what it's doing for you.
00:07:37.360 Let's start with this. This is a simple finder and we're filtering some text over all the users. We want to find all the users with a name like the filter text, and we're interpolating that text right there.
00:07:52.560 Do you see the problem? Everyone should see the problem with this. If you are doing anything like this in your application, you are at security level zero. Your PHP program might give you a pass on that, but in Rails, zing! Do not ever do this in SQL statements.
00:08:06.160 I'm going to turn this over to my hacker-in-residence, Matt, and he's going to actually show you what it looks like.
00:08:17.400 Okay, here's a quick demo. As Jim referenced, the example app here is the movie night application where you can schedule movie nights with friends.
00:08:30.320 We had to bring in an interface that let us expose the data we're showing. We created this listing of users, which you can see, and we added this filter so we can filter by name.
00:08:45.120 If I say I want to filter by Jerry and apply the filter, there we go! Now we only see Jerry, which is imminently useful. But what if we change this a bit?
00:09:03.920 Notice he's hacking the URL directly, going directly into the URL. So we'll just add a little bit of additional what looks like possibly some SQL in here. S1' or '1'='1.
00:09:19.920 Oh look at that! Our list is a little longer! Now you can see the administrator on our site—serious business!
00:09:36.000 Did you see how simple that was? That was just maybe six or seven characters he had to type in to do SQL injection, and he could have done that directly in the filter box too.
00:09:48.000 That's interesting! We could actually do something a little more complex with this and let's just give our filter a little more functionality by trying '1'='1'; DROP TABLE users; --.
00:10:06.480 Now we see the administrator's encrypted password! We've got the encrypted password from the database, ouch! At first, you might think 'Oh, it's encrypted; we're safe!'
00:10:20.560 But you can crack that if the password isn't strong enough. If it's not a good password, that is actually quite easy for hackers to crack.
00:10:36.120 What has happened is we intended for a string like this to be interpolated by clever use of input from the command line, commenting out the remaining SQL and inserting a condition that's always true.
00:10:50.200 We were able to dump the entire user database. We were able to use UNION commands within SQL to pull in fields that were not normally pulled in, and get that data out as well.
00:11:05.160 So, if you can do SQL injection, essentially your database is open for any piece of information to be pulled out of it. What is the solution? Use question marks and the built-in SQL-based interpolation.
00:11:19.920 Pass the parameter as a separate piece that is filled in. The database driver knows about question marks, and it will fill that in without danger of SQL injection.
00:11:34.320 It will quote the comments, and it'll quote appropriately, and you don't have to worry about that. So please, please, please do this! This is the most basic level of security.
00:11:49.520 This is a big problem in Rails, and I was aware of it but not really worried about it. It turns out that the way I write code could have fallen to this vulnerability, but now that I'm aware of it, I can code around it.
00:12:07.240 You do this a lot in Rails: you can update user attributes and just pass up all the parameters in the form that come in like that.
00:12:22.520 Matt, would you demonstrate? Absolutely. So, I can click here and go into edit my profile. I can change a couple of fields here. I could change my name, which I probably won't, or my email address, which actually stayed the same.
00:12:39.600 But what I could do is bring in one of our favorite tools, a DOM inspector, and do a little bit of direct manipulation to try and get around the intended security of the form.
00:12:50.200 So, I drop in and find the email address field for the user and by editing this, I'll say instead of email, I want to set that to true. The 'admin' flag in the database specifies whether you're an administrator or not.
00:13:12.960 So now Mark is now a super admin, and he can run around and do anything that comes to mind. In Rails applications, it's particularly trivial to do this with debugging tools.
00:13:36.319 If there are parameters in your class that need protection from general updates, you need to do one of two things: either use 'attr_accessible' to declare all the fields that a form is allowed to change.
00:13:50.880 Or you use 'attr_protected' to declare all the fields that the form should not change. So, which should we do: accessible or protected? Accessible is better!
00:14:10.440 Why? Because you can maintain what is particularly good. That's why whitelists are better; if you forget something, you’re still protected. A lot of people prefer protected because 'Oh, I've added a field and my form won't work.' But you'd rather deal with temporary annoyance over security issues.
00:14:28.480 The danger with 'attr_accessible' is if you forget to add it to any model, it defaults to everything accessible. So if you're going to use 'attr_accessible,' it's highly recommended to have something in config initializers to account for this.
00:14:44.000 For example, in ActiveRecord::Base you could set 'attr_accessible' to nil. You also need to think more deeply about which fields need to be accessible and which need to remain protected.
00:15:04.880 In essence, if the data isn't owned by the person editing the field, it should be protected. For example, a user should be able to own their name, their password, but the admin flag is not something that can be changed freely.
00:15:20.280 Anything dealing with permissions should be protected. This includes roles and security-related aspects.
00:15:36.680 Always prefer whitelists over blacklists. It's crucial to only list things that are permitted rather than everything that is not permitted. You can't think of everything a hacker might try.
00:15:52.480 Cross-site scripting is another common vulnerability dealing with database data. Let’s demo that.
00:16:07.960 Suppose I want to create a new movie night and invite all my friends. Let’s say I'm pretty confident that everything will work fine.
00:16:23.640 I could write in the notes field something like 'popcorn provided.' I might want to emphasize it, so I think about making it bold.
00:16:41.240 That is, just to be clear, because everybody loves popcorn! But let's see how this actually works when I try to add some HTML and make popcorn bold.
00:16:56.200 I'll just pick something here. So, we really want to ensure people know popcorn will be provided.
00:17:12.720 Let’s see if we can submit that. If we attempt and the process fails because it doesn't interpret our formatting correctly, that would be somewhat disappointing.
00:17:26.440 Okay, so it seems we may have accidentally filtered it. But, bear with me, let’s put just a benign enough form together.
00:17:40.840 I want to make sure we understand this feature we’re working on! Each time we test a cross-site scripting approach, we need to be cautious as this demonstrates the cookie data.
00:18:03.960 Let me try something here with coding. The intention is to showcase how raw output could potentially expose session information.
00:18:23.120 Clearly, there's a risk of data leakage if we do not prevent raw output. If we need raw HTML for any functionality, we must ensure we sanitize it!
00:18:39.280 This is a strong method used across Rails applications allowing you to explicitly control the tag use. Cross-site scripting vulnerabilities are real!
00:18:55.960 Alerts from hacks have occurred before; MySpace lost a significant number of records due to cross-site vulnerabilities.
00:19:11.120 We also must mention that many sites like Twitter have struggled with similar issues! Protecting against cross-site scripting is critical.
00:19:27.720 There's a vulnerability point where a hacker may gain entry and manipulate data corresponding with your permissions.
00:19:44.240 Thus, measures such as privilege escalation can help identify how to remedy access rights once a threat appears.
00:20:01.080 Let’s continue by stressing the importance of proper access control mechanisms for data-sensitive applications.
00:20:21.479 Security should be meta-cognitive; you should always analyze your approaches to managing data-based applications effectively.
00:20:42.679 Let’s shift focus to Cross-Site Request Forgery (CSRF), another significant risk. The reality of web interfaces is that attackers can submit fraudulent requests on behalf of authenticated users.
00:21:04.960 Utilizing token strategies in your Rails administration is the best form of preventative security! The session IDs should therefore always renew as users interact with the site.
00:21:22.719 Also, make sure your application enforces restful methods for modifying stateful resources! You must ensure that your data isn’t altered unnecessarily.
00:21:45.969 You should determine that session and browser interactions remain safe through unique authenticity tokens! All public hosted applications are inherently at risk from these vulnerabilities.
00:22:03.980 Relying solely on HTTPS is an impractical solution; tokens must evolve also! It’s important to maintain distinct communication standards accordingly!
00:22:24.080 Notes also about data handling: do not forget to reliably process your application to filter potential attacks! It leads to best practice security!
00:22:41.280 Cross-site scripting remains relevant consistently, and with further diligence, we must deploy the latest protocols ensuring safety! I want everyone to express this knowledge efficiently!
00:23:02.520 Rapid advances in security must be matched by an equally responsive community! If not effectively communicated, this awareness becomes less impactful.
00:23:17.280 So, always keep security in mind, trust no one, and encourage resilience among fellow developers!
00:23:32.920 Thank you for your attention! Any questions?
Explore all talks recorded at LA RubyConf 2011
+5