diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b5f5d6fc2..7f23d83b6 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -25,7 +25,7 @@ module ApplicationHelper superscript: true } - sanitize(Redcarpet::Markdown.new(renderer, extensions).render(text)) + AdminLegislationSanitizer.new.sanitize(Redcarpet::Markdown.new(renderer, extensions).render(text)) end def wysiwyg(text) diff --git a/app/views/legislation/draft_versions/show.html.erb b/app/views/legislation/draft_versions/show.html.erb index 07814058a..2123fa61b 100644 --- a/app/views/legislation/draft_versions/show.html.erb +++ b/app/views/legislation/draft_versions/show.html.erb @@ -57,7 +57,7 @@
- <%= sanitize(@draft_version.toc_html) %> + <%= AdminLegislationSanitizer.new.sanitize(@draft_version.toc_html) %>
@@ -74,7 +74,7 @@ data-legislation-annotatable-base-url="<%= legislation_process_draft_version_path(@process, @draft_version) %>" data-legislation-open-phase="<%= @process.allegations_phase.open? %>"> <% end %> - <%= sanitize(@draft_version.body_html, { attributes: ["id"] }) %> + <%= AdminLegislationSanitizer.new.sanitize(@draft_version.body_html) %> diff --git a/lib/admin_legislation_sanitizer.rb b/lib/admin_legislation_sanitizer.rb new file mode 100644 index 000000000..103b305b6 --- /dev/null +++ b/lib/admin_legislation_sanitizer.rb @@ -0,0 +1,9 @@ +class AdminLegislationSanitizer < WYSIWYGSanitizer + def allowed_tags + super + %w[img h1 h4 h5 h6] + end + + def allowed_attributes + super + %w[alt src id] + end +end diff --git a/spec/system/xss_spec.rb b/spec/system/xss_spec.rb index 894eec1fb..6b6d2d351 100644 --- a/spec/system/xss_spec.rb +++ b/spec/system/xss_spec.rb @@ -164,12 +164,15 @@ describe "Cross-Site Scripting protection", :js do expect(page.text).not_to be_empty end - scenario "legislation version body filters script tags but not header IDs" do - version = create(:legislation_draft_version, :published, body: "# Title 1\n#{attack_code}") + scenario "legislation version body filters script tags but not header IDs nor tags like images" do + markdown = "# Title 1\nlink" + version = create(:legislation_draft_version, :published, body: "#{markdown}#{attack_code}") visit legislation_process_draft_version_path(version.process, version) expect(page.text).not_to be_empty expect(page).to have_css "h1#title-1", text: "Title 1" + expect(page).to have_link "link", href: "https://domain.com/url" + expect(page).to have_css('img[src="/image.png"') end end