Talks

Securing Your Site

Securing Your Site

by Thomas Pomfret

The video titled 'Securing Your Site', presented by Thomas Pomfret at Rails Conf 2012, addresses best practices for securing Ruby on Rails applications, drawing from experiences gained through high-profile projects and penetration tests. The key points covered include:

  • Understanding Security Needs: It's essential to assess how secure your site needs to be, as different applications have varying levels of security requirements.

  • Common Vulnerabilities:

    • SQL Injection: Highlighted as a major risk, particularly evident from the Open Web Application Security Project (OWASP). The importance of using Rails' built-in protections against SQL injection, such as escaping user inputs, is emphasized.
    • Cross-Site Scripting (XSS): Risks of users injecting scripts into applications are discussed, along with measures to secure cookies and escape user input in Rails applications, especially from version 3 and onwards.
  • Session Management: The talk underscores the significance of secure session practices, suggesting:

    • Using secure cookies to avoid JavaScript access.
    • Implementing session timeouts.
    • Setting unique secret tokens for cookie stores to enhance security.
  • Mass Assignment Vulnerability: Discussed is the need to implement strong protections against mass assignment attacks, recommending the use of whitelisted attributes instead of blacklists.

  • CSRF Protection: Strategies to prevent Cross-Site Request Forgery by using unique tokens for non-GET requests are outlined, utilizing Rails' built-in capabilities.

  • File Uploads and Redirection Risks: Best practices for handling user uploads and redirections to ensure security and validate user input against malicious actions.

  • SSL and Deployment Practices: Advocated the use of SSL across websites and advised proper server configuration to prevent disclosing software version information that could be exploited by attackers.

  • Admin Area Security: Discussed the criticality of securing admin sections, applying standard security principles but with heightened vigilance given the access privileges typically associated with such areas.

In conclusion, Pomfret stresses that while security may seem complex, adopting best practices early in the development process can significantly mitigate risks. The overarching takeaway is to integrate security mindfulness throughout the development lifecycle, applying specific mitigation strategies based on the unique risk profile of each application.

00:00:25.760 So, I'm going to be talking about securing your website and making sure it is secure. It may seem like a dull topic, but I'm pleased to see so many people here.
00:00:33.239 I think it's relevant to anyone working on a web application, and some recent topical events have highlighted this fact again.
00:00:39.920 There’s quite a lot of information on these slides, so I’ll put them online later; don’t try and write everything down. I work at an agency called Mint Digital, based in London and New York.
00:00:52.680 Our clients often ask us to conduct third-party penetration tests, so a lot of this talk is based on experiences from those projects. I’ll look at various areas, but before we dive into specifics, you should ask yourself one key question: how secure does my site need to be?
00:01:05.439 Some sites definitely need to be pretty secure, such as banking applications, but if you’re not operating in that realm, maybe you don’t need to be quite that secure. Security often doesn’t have a right or wrong answer; much of it depends on the risks involved in being hacked. Knowing how secure you need to be puts you in a good position to answer those questions.
00:01:26.320 I’ll strive to keep the examples relevant, so you can see how to apply these practices to your own applications fairly easily.
00:02:00.680 The first topic I’m going to address is SQL injection, mainly because the Open Web Application Security Project (OWASP) lists this as the number one risk for applications.
00:02:07.079 So, what is SQL injection? I think the XKCD comic strip highlights it well: it's when a malicious user can execute some form of SQL query against your database that you wouldn’t want them to.
00:02:18.920 They could do this by injecting SQL into a form field or maybe a GET parameter. Here’s a quick example: someone might put a SQL fragment inside the email field of a login form, which would then be passed along and could be dangerous.
00:02:43.760 Here’s how it can be dangerous. This is an example of controller code where we’re trying to find a user based on the email provided. However, if someone supplies malicious input in that parameter, they could execute problematic SQL.
00:03:01.879 For instance, if this was a login action and the supplied SQL extracted the first user instead of matching a legitimate email, you could be logging someone in who shouldn't have access.
00:03:20.080 How can you prevent this? Fortunately, Rails has built-in protection against SQL injection. To safeguard your application, ensure you're utilizing Rails' inbuilt escaping, which escapes any special characters that MySQL would typically use.
00:03:45.640 If you employ any of the find_by or attribute methods, this happens automatically, so you're covered. If you’re constructing custom conditions using 'where' or 'conditions', you can use array syntax; the parameters will be escaped as well.
00:04:16.639 In summary, just ensure your input is sanitized. With Rails, this is straightforward due to the built-in protection.
00:04:27.880 The next topic is XSS, or Cross-Site Scripting. This occurs when an attacker or malicious user is able to inject code into your site, perhaps through a comment box.
00:04:41.440 This injected code is then executed when a user visits the page. Here are a few examples of attacks that could be carried out. The first one could be considered annoying; it might just prompt a JavaScript pop-up, which isn’t particularly harmful, but still irritating.
00:05:06.720 The next example is more serious: it can send the user's cookies to a third-party site. This could be used to steal the session of a user on Rails who is using cookie storage.
00:05:19.400 Lastly, the attacker might embed an iframe, modifying the appearance of your page and tricking the user into submitting their password or other sensitive information.
00:05:37.800 To mitigate against these threats, first ensure your cookies are secure. There are two relevant options for your cookies: 'httpOnly' and 'secure'. These are both false by default, which means that without manually setting these options, any cookie you set in Rails will be insecure.
00:06:00.400 Setting 'httpOnly' prevents JavaScript from reading the cookie and, while this will protect against someone potentially stealing your session via a script, if you need to read the cookie via JavaScript, you’ll have to weigh that against the potential risk.
00:06:14.479 The second option, 'secure', ensures the cookie is only sent over SSL. If someone makes a request that is not over SSL, the cookie won’t be sent back. Just bear in mind this requires serving any pages that need to utilize that cookie over SSL.
00:06:44.120 Make sure any input submitted by users is escaped before displaying it on the page. To illustrate, in Rails versions prior to 3, this had to be done manually using HTML Escape method, while newer versions do this automatically.
00:07:08.440 In Rails 3 and above, this escaping is automatic, which is great, but if you want to display HTML, such as in an admin CMS where you might want to allow HTML input, you’ll need to use the 'raw' method to mark the string as HTML safe.
00:07:32.240 In summary for XSS, ensure your cookies are secure, especially your session cookie, so it isn’t readable by JavaScript. Also, ensure that any user-submitted input is escaped before you output it. With Rails 3 or above, this escaping happens by default.
00:08:00.320 Now I’ll move on to session management, which includes anything related to login sessions. The primary risk here is session theft.
00:08:14.720 If a third party gains access to a user’s session, they can act on behalf of that user, which is obviously problematic.
00:08:38.680 Rails offers several session stores: since Rails 2, the cookie store has been the default. You also have options like the Cache Store or Active Record Store, which stores sessions in the database. While these stores function similarly, they have different security implications, so it’s essential to understand how they operate.
00:09:17.720 Let’s focus on the cookie store, as it’s the default. The security relies on a secret token in your app’s configuration. It’s only as secure as that token: if you use a weak token, the cookie won’t be secure. There’s a rake task called 'rake secret' that generates a robust token for this purpose.
00:09:55.439 Also, if you have multiple Rails applications, ensure each has a different secret token; otherwise, you could encounter issues. As previously mentioned, XSS is another way to compromise sessions, so avoid vulnerabilities to that.
00:10:42.560 Sessions can also be compromised over insecure networks. A noteworthy plugin called Firesheep showed how easy it could be to hijack sessions on unsecured networks. The cookies are sent with every request. If not over SSL, it’s easy to steal them.
00:11:31.480 To combat this, send everything over SSL. Rails has a setting that ensures every request is secure. While it may seem like a hassle to set up SSL, it’s worth it to bolster your site’s security.
00:12:06.279 It used to be popular to have specific actions over SSL, but this can complicate things. If you provide inconsistencies, it can lead to more challenges than benefits.
00:12:43.120 Make sure that if you allow users to log in, you also allow them to log out. Some sites might require JavaScript or specific actions for logging out. If users can’t log out, they leave the session open, which is not ideal.
00:13:14.040 Also, consider adding session timeouts to prevent them from lingering indefinitely. The default for cookie stores with Rails is to expire at the end of a session, which typically means once the browser window closes.
00:13:44.760 Depending on your application, you should set an appropriate timeout for your sessions. If you want a more secure system, consider shorter session lengths. You can configure this in your session store settings.
00:14:26.640 Whenever a user logs in, it’s good practice to call 'reset session' to create a new one. This invalidates any existing sessions, reducing the risk of session fixation if a hacker already has access to that session.
00:15:11.040 There are a few other considerations in session management that can arise during penetration testing. For example, concurrent logins can involve restricting the same credentials from being logged in more than once.
00:15:25.839 A straightforward method to implement this is to store a unique token when someone logs in and compare that token with the current session whenever that user logs in again.
00:15:42.600 Secondly, account lockout is another option. You can store a counter for failed login attempts, and when it reaches a certain limit, lock that account.
00:15:58.480 It’s beneficial to enforce some password complexity as well, ensuring users can’t create overly simple passwords. You might want to include length requirements as well as checks against dictionary words.
00:16:10.919 Finding a balance between user satisfaction and application security is essential. Once your password policy is established, enforcing it with standard Rails validations is straightforward.
00:16:28.800 Always ensure to terminate sessions properly upon user logout, invalidating the session so it cannot be reused. With the cookie store, simply clearing the cookie won’t kill the session if the cookie is kept elsewhere.
00:17:02.760 If session reuse is a concern for your application, consider an alternative session store such as Cache Store or Active Record Store, as they will invalidate correctly.
00:17:37.320 Hashing passwords is essential. Storing passwords in plain text within your database is a significant security risk; if someone gains access to your database, all of those passwords will be compromised.
00:18:11.720 If you're utilizing the Devise authentication gem, it takes care of this for you. Otherwise, implement hashing by encrypting passwords before saving them.
00:18:50.360 On the topic of password encryption, using bcrypt is recommended over outdated methods like MD5 or SHA. Bcrypt is slower and much more suitable for hashing passwords.
00:19:04.360 When handling sessions, avoid storing any large objects. It’s best to just keep the current user ID within the session. Since cookie stores are user-readable and can easily be left exposed, minimizing the amount of data stored helps maintain security.
00:19:20.960 It's also important to avoid keeping any sensitive information in the session since users can easily tamper with it.
00:19:35.839 To summarize secure practices around sessions: utilize SSL universally, hash any critical data, particularly passwords, and clear sessions when they are no longer needed.
00:19:56.320 Mass assignment is a Rails-specific vulnerability. If someone knows your Rails application version, they could exploit this easily, as seen in some high-profile security breaches.
00:20:25.760 Rails automatically creates getters and setters for model DB columns, which is convenient but can lead to accidental mass assignment if you're not careful.
00:20:37.560 You can prevent mass assignment by using 'attr_protected', which allows you to specify attributes that cannot be set via mass assignment.
00:21:07.400 A better approach is to use 'attr_accessible', which works as a whitelist, specifying which attributes can be mass assigned. This way, even if columns are exposed, only designated attributes will be affected.
00:21:39.320 The whitelisting approach minimizes the risk of overlooking vulnerable attributes. Another option is to implement the 'slice' pattern by filtering allowed parameters in the controller before mass assignment.
00:21:56.480 Quick summary for mass assignment: prioritize 'attr_accessible' methods and look into the 'slice' pattern to enhance security.
00:22:25.680 Direct Object Reference is another critical concern. This involves a malicious user guessing a URL structure to access protected objects.
00:22:53.720 In Rails applications, predictable URLs can be a point of vulnerability. Always ensure that user lookups are performed via session data rather than user-supplied parameters.
00:23:16.880 The Loan Move Pattern suggests not instantiating objects directly in the controller. This ensures that the objects belong to the user that's been associated with their session.
00:23:44.080 This approach can also apply to viewing objects; ensure you're checking ownership before allowing any action.
00:24:06.240 If an object should only be viewed by the creator, check the session to ensure proper permissions are enforced.
00:24:29.880 When it comes to CSRF or Cross-Site Request Forgery, the attack involves including code on a third-party site that can make requests on behalf of an active user.
00:25:06.960 For example, if a user is logged into your site and clicks on a link from an untrusted site, their session could be hijacked, potentially leading to unauthorized actions.
00:25:42.400 To combat CSRF, begin by ensuring all HTTP verbs are used appropriately. For non-safe requests such as POST, PUT, and DELETE, ensure you're validating a unique token to verify that requests are legitimate.
00:26:16.880 The built-in CSRF protection feature in Rails makes this process easy; it generates a hidden form field that validates tokens during submissions.
00:26:43.240 However, be cautious with caching your pages since cached tokens may lead to errors when users submit forms. It’s essential to ensure the token data remains valid.
00:27:08.880 In conclusion on CSRF, use the correct HTTP verbs, ensure validations are in place, and utilize Rails' built-in protections.
00:27:29.160 I want to touch on a couple of topics related to user-submitted information, specifically redirection and uploads. Redirection can be harmless but, if improperly managed, can lead to various security risks.
00:28:42.920 For example, after a user completes an action, properly managing redirection can prevent from being sent to a malicious site; never rely on URL parameters for redirection. Instead, store redirection paths securely in session variables or cookies.
00:29:26.000 When it comes to file uploads, always sanitize filenames or assign your own generated names to eliminate risks of overwriting critical files.
00:30:07.480 Additionally, be diligent in validating file types to prevent any malicious code from being uploaded.
00:30:39.040 If you process images or files that require intensive operations, do so asynchronously to prevent Denial of Service (DoS) vulnerabilities.
00:31:12.480 In summary about uploads: keep redirection logic out of parameters, sanitize filenames, validate content types, and process uploads asynchronously.
00:31:53.120 The importance of SSL cannot be overstated; use it everywhere possible. After setting up SSL, configure your web server to eliminate weaker ciphers to ensure secure transmission.
00:32:31.720 Admin sections of your site require the same security considerations as regular areas, as they grant higher privileges. Ensure that XSS protections apply here, and that admin responses handle inputs securely.
00:33:06.320 Limiting access to admin sections by IP whitelisting can enhance security. Although it may complicate access for users working from various locations, it is a straightforward measure to add.
00:33:57.520 To summarize, all security measures discussed should apply to admin areas with even greater vigilance. Always restrict access to sensitive sections of your application.
00:34:20.720 Moving beyond application code, there are server-side considerations that need focus. Ensure you don’t expose unnecessary details about the software version you’re using to potential hackers.
00:35:13.680 Removing version information from headers is an effective way to enhance security. Always configure your web server to handle error responses gracefully without revealing sensitive application data.
00:36:00.320 An essential aspect of security relates to user privileges; ideally, run all processes under accounts with limited permissions.
00:36:39.280 Ensure that sensitive data, such as passwords, are not logged or leaked in any manner, using filters within your application to protect against this.
00:37:22.720 To conclude, maintain a careful watch on user permissions while being mindful not to leave sensitive information accessible on the server.
00:37:51.320 Finally, I want to share a few resources related to security. The Ruby on Rails Guides feature a good overview of security best practices.
00:38:21.040 The Rails Security Blog provides updates on new vulnerabilities that you need to be aware of, keeping you up-to-date with updates and patches.
00:39:03.760 Brakeman is an excellent gem for code analysis, helping identify various security issues you may need to address.
00:39:45.640 Consider using Tarantula for fuzz testing, helping you identify vulnerabilities by simulating attacks on your application.
00:40:24.520 The OWASP website is a solid resource for best practices and common vulnerabilities applicable across all web applications.
00:41:12.160 Thank you for listening.