From 9bcecab12fbd9f5df5d2d41d3548092a03a9747b Mon Sep 17 00:00:00 2001 From: pabois <pierreandre.boissinot@noesya.coop> Date: Fri, 25 Feb 2022 09:35:04 +0100 Subject: [PATCH] sanitizer --- .../administration/qualiopi/criterion.rb | 2 ++ .../administration/qualiopi/indicator.rb | 2 ++ app/models/communication/website/category.rb | 1 + .../communication/website/index_page.rb | 1 + app/models/communication/website/menu.rb | 1 + app/models/communication/website/menu/item.rb | 1 + app/models/communication/website/page.rb | 1 + app/models/communication/website/post.rb | 1 + app/models/concerns/sanitizable.rb | 21 +++++++++++++ app/models/education/program.rb | 1 + app/models/research/journal/article.rb | 1 + app/models/research/journal/volume.rb | 1 + app/models/research/laboratory/axis.rb | 1 + app/models/research/thesis.rb | 2 ++ app/models/university/person.rb | 1 + app/services/osuny/sanitizer.rb | 31 +++++++++++++++++++ config/application.rb | 4 +-- 17 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 app/models/concerns/sanitizable.rb create mode 100644 app/services/osuny/sanitizer.rb diff --git a/app/models/administration/qualiopi/criterion.rb b/app/models/administration/qualiopi/criterion.rb index b4ffaec5e..28bca2dce 100644 --- a/app/models/administration/qualiopi/criterion.rb +++ b/app/models/administration/qualiopi/criterion.rb @@ -10,6 +10,8 @@ # updated_at :datetime not null # class Administration::Qualiopi::Criterion < ApplicationRecord + include Sanitizable + has_many :indicators, dependent: :destroy validates :number, uniqueness: true diff --git a/app/models/administration/qualiopi/indicator.rb b/app/models/administration/qualiopi/indicator.rb index c43737ece..6e06a0273 100644 --- a/app/models/administration/qualiopi/indicator.rb +++ b/app/models/administration/qualiopi/indicator.rb @@ -23,6 +23,8 @@ # fk_rails_eed87f7acf (criterion_id => administration_qualiopi_criterions.id) # class Administration::Qualiopi::Indicator < ApplicationRecord + include Sanitizable + belongs_to :criterion validates :number, uniqueness: true diff --git a/app/models/communication/website/category.rb b/app/models/communication/website/category.rb index 5dd734d33..28be40150 100644 --- a/app/models/communication/website/category.rb +++ b/app/models/communication/website/category.rb @@ -33,6 +33,7 @@ # fk_rails_e58348b119 (program_id => education_programs.id) # class Communication::Website::Category < ApplicationRecord + include Sanitizable include WithGit include WithFeaturedImage include WithBlobs diff --git a/app/models/communication/website/index_page.rb b/app/models/communication/website/index_page.rb index 9366722a9..049d93274 100644 --- a/app/models/communication/website/index_page.rb +++ b/app/models/communication/website/index_page.rb @@ -27,6 +27,7 @@ # fk_rails_7eb45227ae (university_id => universities.id) # class Communication::Website::IndexPage < ApplicationRecord + include Sanitizable include WithGit include WithFeaturedImage include WithBlobs diff --git a/app/models/communication/website/menu.rb b/app/models/communication/website/menu.rb index 2ec3ea11b..2e21098b7 100644 --- a/app/models/communication/website/menu.rb +++ b/app/models/communication/website/menu.rb @@ -22,6 +22,7 @@ # fk_rails_dcc7198fc5 (communication_website_id => communication_websites.id) # class Communication::Website::Menu < ApplicationRecord + include Sanitizable include WithGit belongs_to :university diff --git a/app/models/communication/website/menu/item.rb b/app/models/communication/website/menu/item.rb index d95a6563b..f4980a465 100644 --- a/app/models/communication/website/menu/item.rb +++ b/app/models/communication/website/menu/item.rb @@ -32,6 +32,7 @@ # fk_rails_fa4f4585e4 (website_id => communication_websites.id) # class Communication::Website::Menu::Item < ApplicationRecord + include Sanitizable include WithTree include WithPosition include WithTargets diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb index 7aa7eee02..7ee31a9de 100644 --- a/app/models/communication/website/page.rb +++ b/app/models/communication/website/page.rb @@ -39,6 +39,7 @@ # class Communication::Website::Page < ApplicationRecord + include Sanitizable include WithGit include WithFeaturedImage include WithBlobs diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb index 0cd59f91a..80c4c0218 100644 --- a/app/models/communication/website/post.rb +++ b/app/models/communication/website/post.rb @@ -32,6 +32,7 @@ # fk_rails_e0eec447b0 (author_id => university_people.id) # class Communication::Website::Post < ApplicationRecord + include Sanitizable include WithGit include WithFeaturedImage include WithBlobs diff --git a/app/models/concerns/sanitizable.rb b/app/models/concerns/sanitizable.rb new file mode 100644 index 000000000..1d9b39065 --- /dev/null +++ b/app/models/concerns/sanitizable.rb @@ -0,0 +1,21 @@ +module Sanitizable + extend ActiveSupport::Concern + + included do + + before_validation :sanitize_fields + + def sanitize_fields + attributes_to_sanitize = self.class.columns_hash.map { |name,value| [name, value.type] } + .to_h + .select { |attr_name, attr_type| + [:string, :text].include?(attr_type) && public_send(attr_name).present? + } + + attributes_to_sanitize.each do |attr_name, attr_type| + public_send "#{attr_name}=", Osuny::Sanitizer.sanitize(public_send(attr_name), attr_type) + end + end + + end +end diff --git a/app/models/education/program.rb b/app/models/education/program.rb index 5d9827e76..69cc14e8e 100644 --- a/app/models/education/program.rb +++ b/app/models/education/program.rb @@ -43,6 +43,7 @@ # fk_rails_ec1f16f607 (parent_id => education_programs.id) # class Education::Program < ApplicationRecord + include Sanitizable include WithGit include WithFeaturedImage include WithBlobs diff --git a/app/models/research/journal/article.rb b/app/models/research/journal/article.rb index 10366cfd8..632708ee1 100644 --- a/app/models/research/journal/article.rb +++ b/app/models/research/journal/article.rb @@ -34,6 +34,7 @@ # fk_rails_935541e014 (university_id => universities.id) # class Research::Journal::Article < ApplicationRecord + include Sanitizable include WithGit include WithBlobs include WithPosition diff --git a/app/models/research/journal/volume.rb b/app/models/research/journal/volume.rb index 30c6db4a0..719f76d55 100644 --- a/app/models/research/journal/volume.rb +++ b/app/models/research/journal/volume.rb @@ -27,6 +27,7 @@ # fk_rails_c83d5e9068 (university_id => universities.id) # class Research::Journal::Volume < ApplicationRecord + include Sanitizable include WithGit include WithBlobs include WithFeaturedImage diff --git a/app/models/research/laboratory/axis.rb b/app/models/research/laboratory/axis.rb index 11e2f3d15..40cae3951 100644 --- a/app/models/research/laboratory/axis.rb +++ b/app/models/research/laboratory/axis.rb @@ -24,6 +24,7 @@ # fk_rails_d334f832b4 (university_id => universities.id) # class Research::Laboratory::Axis < ApplicationRecord + include Sanitizable include WithPosition has_summernote :text diff --git a/app/models/research/thesis.rb b/app/models/research/thesis.rb index 0d824cbfb..48f1f4aed 100644 --- a/app/models/research/thesis.rb +++ b/app/models/research/thesis.rb @@ -30,6 +30,8 @@ # fk_rails_b3380066dc (research_laboratory_id => research_laboratories.id) # class Research::Thesis < ApplicationRecord + include Sanitizable + belongs_to :university belongs_to :laboratory, foreign_key: :research_laboratory_id belongs_to :author, class_name: 'University::Person' diff --git a/app/models/university/person.rb b/app/models/university/person.rb index 49718973f..05eaa9662 100644 --- a/app/models/university/person.rb +++ b/app/models/university/person.rb @@ -31,6 +31,7 @@ # fk_rails_da35e70d61 (university_id => universities.id) # class University::Person < ApplicationRecord + include Sanitizable include WithGit include WithBlobs include WithSlug diff --git a/app/services/osuny/sanitizer.rb b/app/services/osuny/sanitizer.rb new file mode 100644 index 000000000..a155edb89 --- /dev/null +++ b/app/services/osuny/sanitizer.rb @@ -0,0 +1,31 @@ +class Osuny::Sanitizer + include ActionView::Helpers::SanitizeHelper + + def self.sanitize(input, type = 'text') + return '' if input.blank? + raise ArgumentError.new('First argument must be a String') unless [String, ActionText::Content].include? input.class + + case type.to_s + when 'string' + string_sanitize(input) + when 'text' + if input.is_a? String + safe_list_sanitizer.sanitize input + else + ActionText::Content.new(safe_list_sanitizer.sanitize input.to_html) + end + else + input + end + end + + private + + def self.string_sanitize(raw_string) + output = Loofah.fragment(raw_string).text(encode_special_chars: false) + while output != Loofah.fragment(output).text(encode_special_chars: false) + output = Loofah.fragment(output).text(encode_special_chars: false) + end + output + end +end diff --git a/config/application.rb b/config/application.rb index 6dbe81158..010539967 100644 --- a/config/application.rb +++ b/config/application.rb @@ -53,14 +53,14 @@ module Osuny "cite", "code", "dd", "del", "dfn", "div", "dl", "dt", "em", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "img", "ins", "kbd", "li", "ol", "p", "picture", "pre", "samp", "small", "source", "span", "strong", - "sub", "sup", "tt", "u", "ul", "var", "video", "iframe" + "sub", "sup", "tt", "u", "ul", "var", "video", "iframe", "action-text-attachment" ] config.action_view.sanitized_allowed_attributes = [ "abbr", "allowfullscreen", "alt", "cite", "controls", "datetime", "decoding", "frameborder", "height", "href", "loading", "mozallowfullscreen", "name", "sizes", "src", "srcset", "target", "title", "type", "webkitallowfullscreen", "width", "xml:lang", - + "sgid", "content-type", "url", "filename", "filesize", "previewable" ] config.allowed_special_chars = '#?!,@$%^&*+:;£µ-' -- GitLab