DEV Community

Eugene Komissarov
Eugene Komissarov

Posted on • Originally published at jetrockets.pro

Save your links from phishers.

While Pull Request fixing issue with OWASP Tabnabbing is still open... since Feb 16, 2017, our shiny Rails applications are in danger. But wait no longer! Just put code like this:

# frozen_string_literal: true

module ActionView
  module Helpers #:nodoc:
      module UrlHelper
      # Same as #link_to, but also adds rel="nofollow" and rel="noopener" if target="_blank"
      #   rel='noopener' is added to mitigate OWASP Reverse Tabnabbing
      #
      #   external_link_to "External link", "http://www.rubyonrails.org/", target: "_blank"
      #   # => <a href="http://www.rubyonrails.org/" target="_blank" rel="nofollow noopener">External link</a>
      def external_link_to(name = nil, options = nil, html_options = nil, &block)
        html_options, options, name = options, name, yield if block_given?
        html_options ||= {}
        html_options.stringify_keys!

        html_options['rel'.freeze] = "#{html_options['rel'.freeze]} nofollow".lstrip
        html_options['rel'.freeze] = "#{html_options['rel'.freeze]} noopener".lstrip if html_options['target'.freeze] == '_blank'.freeze
        link_to(name, options, html_options)
      end
    end
  end
end

into one of initializers and enjoy bit of safety. This will add new url helper external_link_to to your disposal, that will mitigate Reverse Tabnabbing endangering your application.

Or, if you feel adventurous today... lets patch link_to itself!

# frozen_string_literal: true

module ActionView
  module Helpers #:nodoc:
    module UrlHelper

      def link_to(name = nil, options = nil, html_options = nil, &block)
        html_options, options, name = options, name, block if block_given?
        options ||= {}


        html_options = convert_options_to_data_attributes(options, html_options)

        html_options['rel'.freeze] = "#{html_options['rel'.freeze]} nofollow".lstrip
        html_options['rel'.freeze] = "#{html_options['rel'.freeze]} noopener".lstrip if html_options['target'.freeze] == '_blank'.freeze

        url = url_for(options)
        html_options["href".freeze] ||= url

        content_tag("a".freeze, name || url, html_options, &block)
      end
    end
  end
end

Even better! Now all your existing links with target="_blank" gonna be safe from nasty fishers.

Happy coding and stay safe.

Top comments (0)