Commit 08bfec57 authored by Jan Provaznik's avatar Jan Provaznik

Set URL rel attribute for broken URLs

It's possible that URI fails to parse a link, but browsers
still recognize given URL as a link, we should make sure
that 'rel' attribute is set also in this case.
parent 18a48e34
---
title: Set URL rel attribute for broken URLs.
merge_request:
author:
type: security
...@@ -9,11 +9,10 @@ module Banzai ...@@ -9,11 +9,10 @@ module Banzai
def call def call
links.each do |node| links.each do |node|
uri = uri(node['href'].to_s) uri = uri(node['href'].to_s)
next unless uri
node.set_attribute('href', uri.to_s) node.set_attribute('href', uri.to_s) if uri
if SCHEMES.include?(uri.scheme) && external_url?(uri) if SCHEMES.include?(uri&.scheme) && !internal_url?(uri)
node.set_attribute('rel', 'nofollow noreferrer noopener') node.set_attribute('rel', 'nofollow noreferrer noopener')
node.set_attribute('target', '_blank') node.set_attribute('target', '_blank')
end end
...@@ -35,11 +34,12 @@ module Banzai ...@@ -35,11 +34,12 @@ module Banzai
doc.xpath(query) doc.xpath(query)
end end
def external_url?(uri) def internal_url?(uri)
return false if uri.nil?
# Relative URLs miss a hostname # Relative URLs miss a hostname
return false unless uri.hostname return true unless uri.hostname
uri.hostname != internal_url.hostname uri.hostname == internal_url.hostname
end end
def internal_url def internal_url
......
...@@ -49,16 +49,16 @@ describe Banzai::Filter::ExternalLinkFilter do ...@@ -49,16 +49,16 @@ describe Banzai::Filter::ExternalLinkFilter do
end end
context 'for invalid urls' do context 'for invalid urls' do
it 'skips broken hrefs' do it 'adds rel and target attributes to broken hrefs' do
doc = filter %q(<p><a href="don't crash on broken urls">Google</a></p>) doc = filter %q(<p><a href="don't crash on broken urls">Google</a></p>)
expected = %q(<p><a href="don't%20crash%20on%20broken%20urls">Google</a></p>) expected = %q(<p><a href="don't%20crash%20on%20broken%20urls" rel="nofollow noreferrer noopener" target="_blank">Google</a></p>)
expect(doc.to_html).to eq(expected) expect(doc.to_html).to eq(expected)
end end
it 'skips improperly formatted mailtos' do it 'adds rel and target to improperly formatted mailtos' do
doc = filter %q(<p><a href="mailto://jblogs@example.com">Email</a></p>) doc = filter %q(<p><a href="mailto://jblogs@example.com">Email</a></p>)
expected = %q(<p><a href="mailto://jblogs@example.com">Email</a></p>) expected = %q(<p><a href="mailto://jblogs@example.com" rel="nofollow noreferrer noopener" target="_blank">Email</a></p>)
expect(doc.to_html).to eq(expected) expect(doc.to_html).to eq(expected)
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment