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.