diff --git a/app/controllers/note_previews_controller.rb b/app/controllers/note_previews_controller.rb index 81c464689..e14f0b1c5 100644 --- a/app/controllers/note_previews_controller.rb +++ b/app/controllers/note_previews_controller.rb @@ -2,7 +2,7 @@ class NotePreviewsController < ApplicationController respond_to :json def show - @body = DText.sanitize(params[:body].to_s) + @body = NoteSanitizer.sanitize(params[:body].to_s) respond_with(@body) do |format| format.json do render :json => {:body => @body}.to_json diff --git a/app/logical/d_text.rb b/app/logical/d_text.rb index 78aaf56d0..0ac557ee3 100644 --- a/app/logical/d_text.rb +++ b/app/logical/d_text.rb @@ -369,30 +369,6 @@ class DText s end - def self.sanitize(text) - text.gsub!(/<( |-|3|:|>|\Z)/, "<\\1") - - Sanitize.clean( - text, - :elements => %w(code center tn h1 h2 h3 h4 h5 h6 a span div blockquote br p ul li ol em strong small big b i font u s pre ruby rb rt rp), - :attributes => { - "a" => %w(href title style), - "span" => %w(class style), - "div" => %w(class style align), - "p" => %w(class style align), - "font" => %w(color size style) - }, - :protocols => { - "a" => { - "href" => ["http", "https", :relative] - } - }, - :css => Sanitize::Config::RELAXED[:css].merge({ - :protocols => [] - }) - ) - end - # extract the first paragraph `needle` occurs in. def self.excerpt(dtext, needle) dtext = dtext.gsub(/\r\n|\r|\n/, "\n") diff --git a/app/logical/note_sanitizer.rb b/app/logical/note_sanitizer.rb new file mode 100644 index 000000000..27ca58345 --- /dev/null +++ b/app/logical/note_sanitizer.rb @@ -0,0 +1,79 @@ +module NoteSanitizer + ALLOWED_ELEMENTS = %w( + code center tn h1 h2 h3 h4 h5 h6 a span div blockquote br p ul li ol em + strong small big b i font u s pre ruby rb rt rp rtc sub sup hr wbr + ) + + ALLOWED_ATTRIBUTES = { + :all => %w(style title), + "a" => %w(href), + "span" => %w(class), + "div" => %w(class align), + "p" => %w(class align), + "font" => %w(color size), + } + + ALLOWED_PROPERTIES = %w( + background background-color + border border-color border-image border-radius border-style border-width + border-bottom border-bottom-color border-bottom-left-radius border-bottom-right-radius border-bottom-style border-bottom-width + border-left border-left-color border-left-style border-left-width + border-right border-right-color border-right-style border-right-width + border-top border-top-color border-top-left-radious border-top-right-radius border-top-style border-top-width + bottom left right top + box-shadow + clear + color + display + filter + float + font font-family font-size font-size-adjust font-style font-variant font-weight + height width + letter-spacing + line-height + list-style list-style-position list-style-type + margin margin-bottom margin-left margin-right margin-top + opacity + outline outline-color outline-offset outline-width outline-style + padding padding-bottom padding-left padding-right padding-top + perspective perspective-origin + position + text-align + text-decoration text-decoration-color text-decoration-line text-decoration-style + text-indent + text-shadow + text-transform + transform transform-origin + white-space + word-break + word-spacing + word-wrap overflow-wrap + writing-mode + vertical-align + ) + + def self.sanitize(text) + text.gsub!(/<( |-|3|:|>|\Z)/, "<\\1") + + Sanitize.clean( + text, + :elements => ALLOWED_ELEMENTS, + :attributes => ALLOWED_ATTRIBUTES, + :add_attributes => { + "a" => { "rel" => "nofollow" }, + }, + :protocols => { + "a" => { + "href" => ["http", "https", :relative] + } + }, + :css => { + allow_comments: false, + allow_hacks: false, + at_rules: [], + protocols: [], + properties: ALLOWED_PROPERTIES, + } + ) + end +end diff --git a/app/views/notes/_note.html.erb b/app/views/notes/_note.html.erb index fcf1b3dff..15e374b34 100644 --- a/app/views/notes/_note.html.erb +++ b/app/views/notes/_note.html.erb @@ -1 +1 @@ -
<%= raw DText.sanitize(note.body) %>
+
<%= raw NoteSanitizer.sanitize(note.body) %>
diff --git a/test/unit/note_sanitizer_test.rb b/test/unit/note_sanitizer_test.rb new file mode 100644 index 000000000..e87ed67d7 --- /dev/null +++ b/test/unit/note_sanitizer_test.rb @@ -0,0 +1,25 @@ +require 'test_helper' + +class NoteSanitizerTest < ActiveSupport::TestCase + context "Sanitizing a note" do + should "strip unsafe tags" do + body = '

test

' + assert_equal('

test

alert("owned")', NoteSanitizer.sanitize(body)) + end + + should "strip unsafe css" do + body = '

test

' + assert_equal("

test

", NoteSanitizer.sanitize(body)) + end + + should "allow style attributes on every tag" do + body = '

test

' + assert_equal('

test

', NoteSanitizer.sanitize(body)) + end + + should "mark links as nofollow" do + body = 'google' + assert_equal('google', NoteSanitizer.sanitize(body)) + end + end +end