Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Rails and Content Security Policies

My talk for the October 2016 Helsinki Ruby Brigade meet-up. What CSPs are, why to use a CSP, and how to implement a CSP header with Rails.

  • Login to see the comments

Rails and Content Security Policies

  1. 1. Ruby Brigade 10/2016 Rails and Content Security Policies
  2. 2. Who am I? • A developer at Kisko Labs • In my free 8me I work on too many side projects • piranhas.co — a book price comparison site and app • Beer Styles — an iOS app for browsing beer style guidelines • TLS.caresoon! — an SSL/TLS cer8ficate monitoring service • and I also brew beer
  3. 3. Kisko Labs We build and launch tools on the web Are you a Ruby or frontend developer? We're hiring
  4. 4. CSPContent Security Policy
  5. 5. Content Security Policy is an added layer of security that helps to detect and mi3gate certain types of a5acks, including Cross Site Scrip3ng (XSS) and data injec3on a5acks. — MDN
  6. 6. Content Security Policy: a header which tells the browser where resources (scripts, stylesheets, fonts, etc) can be loaded from. — Me
  7. 7. Supported by all major browsers, even Internet Explorer (kind of)
  8. 8. CSP: Why? • Reduces the poten.al surface area for a3acks or malicious injec.on of scripts • Prevents malicious browser extensions and malware from inser.ng crap into your pages. • For example, the CSP on Piranhas.co has stopped some shady browser extensions from injec.ng ads? onto the page.
  9. 9. https://static.cmptch.com
  10. 10. I don't know what this is, but I know that I don't want it on my site!
  11. 11. CSP Direc*ves Content Security Policies allow quite fine grained control over what can be loaded from where. For example, you can allow scripts from a domain but not images (or vice versa). Or, for example, if you allow users to upload images, but not scripts, you can segregate user uploads to a specific host (“allow images from uploads.example.com but nothing else”).
  12. 12. Available direc,ves • default-src: Define loading policy for all resources type in case of a resource type dedicated direc5ve is not defined (fallback), • script-src: Define which scripts the protected resource can execute, • object-src: Define from where the protected resource can load plugins, • style-src: Define which styles (CSS) the user applies to the protected resource,
  13. 13. • img-src: Define from where the protected resource can load images, • media-src: Define from where the protected resource can load video and audio, • frame-src: Define from where the protected resource can embed frames, • font-src: Define from where the protected resource can load fonts,
  14. 14. • connect-src: Define which URIs the protected resource can load using script interfaces, • form-ac-on: Define which URIs can be used as the ac;on of HTML form elements, • sandbox: Specifies an HTML sandbox policy that the user agent applies to the protected resource, • script-nonce: Define script execu;on by requiring the presence of the specified nonce on script elements,
  15. 15. • plugin-types: Define the set of plugins that can be invoked by the protected resource by limi:ng the types of resources that can be embedded, • reflected-xss: Instructs a user agent to ac:vate or deac:vate any heuris:cs used to filter or block reflected cross-site scrip:ng a?acks, equivalent to the effects of the non-standard X-XSS- Protec:on header, • report-uri: Specifies a URI to which the user agent sends reports about policy viola:on
  16. 16. Adding a CSP header to a long standing site can be … tricky
  17. 17. CSP example (piranhas.co) Content-Security-Policy: default-src https:; style-src 'unsafe-inline' https://cdn.piranhas.xyz https://fonts.googleapis.com; script-src 'unsafe-inline' 'unsafe-eval' https://cdn.piranhas.xyz https://www.google-analytics.com https://suggestqueries.google.com https://www.googleapis.com; img-src data: https:; report-uri https://x.report-uri.io/r/default/csp/enforce; (line breaks added for clarity…)
  18. 18. Adding it from the very beginning is a lot easier…
  19. 19. CSP example (simplified) Content-Security-Policy: default-src *; Allow all sources, but disallow unsafe inline assets (for example scripts and styles).
  20. 20. CSP example (simplified alterna3ve) Content-Security-Policy: default-src 'self'; Allow all sources, but disallow unsafe inline assets (for example scripts and styles).
  21. 21. 'unsafe-inline' vs “safe inline” • By default inline scripts are blocked • You can either • add 'unsafe-inline' to your CSP (in which case you're back where your started) • or use inline scripts with a nonce (more on this later)
  22. 22. In cryptography, a nonce is an arbitrary number that may only be used once. — Wikipedia
  23. 23. You specify the nonce in the CSP header: Content-Security-Policy: ... script-src 'nonce-/jRAxuLJsDXAxqhNBB7gg7h55KETtDQBXe4ZL+xIXwI=' ...; and in your <script> (or <style>) tag: <script nonce="/jRAxuLJsDXAxqhNBB7gg7h55KETtDQBXe4ZL+xIXwI="> console.log("Hello World") </script> The browser will allow each nonce to be used only once…
  24. 24. Secure Headers
  25. 25. Secure Headers A Rack middleware gem from Twi2er which adds support for more security headers than are available by default in Rails. • h#ps://github.com/twi#er/secureheaders • h#ps://rubygems.org/gems/secure_headers Makes it easier to use CSP headers (and it also handles other security headers)
  26. 26. Secure Headers It lets you define an app-wide CSP that you can override or append to at a controller or ac9on level. Don't just add it though. Look through the configura6on and understand what it's doing. You might want to disable some of the op6ons.
  27. 27. Secure Headers It's a pre*y extensive library, so read the README to learn more.
  28. 28. Secure Headers: nonces It also includes support for safe inline styles and scripts using nonces. For example: <%= nonced_javascript_tag do %> console.log("nonced!"); <% end %>
  29. 29. Secure Headers: nonces Generates this HTML: <script nonce="/jRAxuLJsDXAxqhNBB7gg7h55KETtDQBXe4ZL+xIXwI="> console.log("nonced!") </script> And adds this to the CSP header: Content-Security-Policy: ... script-src 'nonce-/jRAxuLJsDXAxqhNBB7gg7h55KETtDQBXe4ZL+xIXwI=' ...;
  30. 30. Secure Headers: minimal configura3on # config/initializers/secure_headers.rb SecureHeaders::Configuration.default do |config| config.csp = { default_src: %w(*), upgrade_insecure_requests: Rails.env.production?, # see https://www.w3.org/TR/upgrade-insecure-requests/ report_uri: %w(https://x.report-uri.io/r/default/csp/enforce) } config.hpkp = SecureHeaders::OPT_OUT end Or you might want to use 'self' instead of *
  31. 31. Secure Headers Rails also sets some of the same security headers, but Secure Headers has code to override those with its own configura;on. => Secure Headers knows how to play nice with Rails
  32. 32. => Secure Headers knows how to play nice with Rails isolate_namespace SecureHeaders if defined? isolate_namespace # rails 3.0 conflicting_headers = ['X-Frame-Options', 'X-XSS-Protection', 'X-Permitted-Cross-Domain-Policies', 'X-Download-Options', 'X-Content-Type-Options', 'Strict-Transport-Security', 'Content-Security-Policy', 'Content-Security-Policy-Report-Only', 'Public-Key-Pins', 'Public-Key-Pins-Report-Only', 'Referrer-Policy'] # ... conflicting_headers.each do |header| Rails.application.config.action_dispatch.default_headers.delete(header) end h"ps://github.com/twi"er/secureheaders/blob/v3.4.1/lib/ secure_headers/rail;e.rb
  33. 33. CSP pro-)ps
  34. 34. CSP pro-)ps Start by using the Content-Security-Policy-Report-Only header to test and tweak your CSP header in the wild. Content-Security-Policy-Report-Only: default-src *, report-uri https://x.report-uri.io/r/default/csp/enforce;; Deploy the Report Only header for a few days before star1ng to enforce it.
  35. 35. CSP pro-)ps • New projects • Enforce the CSP from the beginning • Report viola<ons from your staging or produc<on environment • Old projects • Add a CSP with all the sources you think you need • Deploy it as Report Only, leave it for a week or two to uncover anything you might have forgoEen about • Deploy the enforced policy once you've accounted for all the viola<ons • Both • When making changes, you may wish to first test them with the Report Only header (depending on the change)
  36. 36. CSP resources • h#ps://sco#helme.co.uk/content-security-policy-an- introduc8on/ • h#ps://report-uri.io • h#ps://developer.mozilla.org/en-US/docs/Web/Security/CSP/ Using_Content_Security_Policy
  37. 37. CSP resources • h#ps://github.com/twi#er/secureheaders • h#ps://security.googleblog.com/2016/09/reshaping-web- defenses-with-strict.html • CSP Evaluator: h#ps://csp-evaluator.withgoogle.com/ • CSP MiGgator: h#ps://chrome.google.com/webstore/detail/ csp-miGgator/gijlobangojajlbodabkpjpheeeokhfa
  38. 38. Summary
  39. 39. Summary • Rails defaults are pre/y good, but can be (fairly easily) be 9ghtened • Use a Content Security Policy, if only to prevent ad/malware injec9on by compromised browsers • The more strict the CSP is, the fewer chances there are for third par9es to mess with your site • Use the Secure Headers gem to manage the CSP policy and other security headers • It requires more thought than the Rails defaults, but I think it's worth it • Excep&on to all of the above: If you're working on your first Rails app, you probably shouldn't add this complexity.
  40. 40. Thanks
  41. 41. Ma#as Korhonen @ma$askorhonen ma#askorhonen.fi piranhas.co Beer Styles TLS.caresoon!

×