diff --git a/app/models/administration/qualiopi/criterion.rb b/app/models/administration/qualiopi/criterion.rb
index b4ffaec5e8d944bc9f2a9c811b2f02e20c2bc583..28bca2dce9bc7b784c2bac4b599edfb8fcd9c0d6 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 c43737ecec0ff0f33f11a12b85d2730fc6652174..6e06a027333a734dbc6b5b039d18b1b21626969a 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 5dd734d333071506412a4ca21bb1fdc9b5f39006..28be4015004733c0584bb791c3ec262af4f577b8 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 9366722a9032e4ff6b052d144970edb5846c130d..049d93274f930524a58782b84713c59e9185768f 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 2ec3ea11b4b91177e4942398e0d2616f13a8518a..2e21098b71da60df7718b6c4cafc3b213cdf2f5c 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 d95a6563bdbd9b97618bb1d37934c2f0d2521df3..f4980a4655b27ce1fb73ebbb489a05fe4c9f5f4b 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 7aa7eee02bfbf1bba58716c63435a311d22d93ab..7ee31a9de34c55513239870fc53ea7019c98bbed 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 0cd59f91a802279033b58dea9fef6f14f5fe9c2e..80c4c0218cf26f5adedb2d1453dfe7412e26cb66 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 0000000000000000000000000000000000000000..1d9b3906576f0dfbcd5ebcd97b9a20d3598404aa
--- /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 5d9827e766853026b9be2348ad1c87af96a299f7..69cc14e8e4ae5b1e677a7f81b14dd8d10d358d88 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 10366cfd8229c1d20e961cf93ba22124f96eefdc..632708ee1b3197dbfc240cb14642dd11d1e0110f 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 30c6db4a0dd9a920a2b18e0a68408bc3d4e5a0b7..719f76d558e40fc8690ddd529a48046da3527742 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 11e2f3d15423984867cb20a04840df99da6014b4..40cae3951f593bcdbdf768e46945d393921becca 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 0d824cbfb40cddf7ca85d22329bfc38f7f84a5f9..48f1f4aed7fef891888d8c82c865841d681da385 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 49718973f6abed6db2b9bf4b1e863f47a5e4bb4b..05eaa96626d74e0547960a3dc86c8f468d66c7fc 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 0000000000000000000000000000000000000000..a155edb894630030dff6830a5c677932db4ca6ef
--- /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 6dbe81158b8851969714c9e89215316baf885edc..01053996716cd1195dc5e8473bf7fa66b84f2bc9 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 = '#?!,@$%^&*+:;£µ-'