class RuboCop::Cop::Rails::LinkToBlank
This cop checks for calls to `link_to` that contain a `target: '_blank'` but no `rel: 'noopener'`. This can be a security risk as the loaded page will have control over the previous page and could change its location for phishing purposes.
The option `rel: 'noreferrer'` also blocks this behavior and removes the http-referrer header.
@example
# bad link_to 'Click here', url, target: '_blank' # good link_to 'Click here', url, target: '_blank', rel: 'noopener' # good link_to 'Click here', url, target: '_blank', rel: 'noreferrer'
Constants
- MSG
- RESTRICT_ON_SEND
Public Instance Methods
on_send(node)
click to toggle source
# File lib/rubocop/cop/rails/link_to_blank.rb, line 41 def on_send(node) option_nodes = node.each_child_node(:hash) option_nodes.map(&:children).each do |options| blank = options.find { |o| blank_target?(o) } next unless blank && options.none? { |o| includes_noopener?(o) } add_offense(blank) do |corrector| autocorrect(corrector, node, blank, option_nodes) end end end
Private Instance Methods
add_rel(send_node, offense_node, corrector)
click to toggle source
# File lib/rubocop/cop/rails/link_to_blank.rb, line 78 def add_rel(send_node, offense_node, corrector) opening_quote = offense_node.children.last.source[0] closing_quote = opening_quote == ':' ? '' : opening_quote new_rel_exp = ", rel: #{opening_quote}noopener#{closing_quote}" range = if (last_argument = send_node.last_argument).hash_type? last_argument.pairs.last.source_range else last_argument.source_range end corrector.insert_after(range, new_rel_exp) end
append_to_rel(rel_node, corrector)
click to toggle source
# File lib/rubocop/cop/rails/link_to_blank.rb, line 69 def append_to_rel(rel_node, corrector) existing_rel = rel_node.children.last.value str_range = rel_node.children.last.loc.expression.adjust( begin_pos: 1, end_pos: -1 ) corrector.replace(str_range, "#{existing_rel} noopener") end
autocorrect(corrector, send_node, node, option_nodes)
click to toggle source
# File lib/rubocop/cop/rails/link_to_blank.rb, line 56 def autocorrect(corrector, send_node, node, option_nodes) rel_node = nil option_nodes.map(&:children).each do |options| rel_node ||= options.find { |o| rel_node?(o) } end if rel_node append_to_rel(rel_node, corrector) else add_rel(send_node, node, corrector) end end
contains_noopener?(value)
click to toggle source
# File lib/rubocop/cop/rails/link_to_blank.rb, line 91 def contains_noopener?(value) return false unless value rel_array = value.to_s.split rel_array.include?('noopener') || rel_array.include?('noreferrer') end