diff --git a/Gemfile b/Gemfile
index 40aa0db98ff947dab93647635daded27937dfe36..df6f772a13e2f24f311b16eb7f0ede426128f59a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,84 +1,85 @@
-source 'https://rubygems.org'
+source "https://rubygems.org"
 git_source(:github) { |repo| "https://github.com/#{repo}.git" }
 
-ruby '3.1.3'
+ruby "3.1.3"
 
 # Infrastructure
-gem 'activestorage-scaleway-service'#, path: '../activestorage-scaleway-service'
-gem 'angularjs-rails'
-gem 'aws-sdk-s3'
-gem 'bootstrap'
-gem 'bootsnap', '>= 1.4.4', require: false
-gem 'bootstrap5-kaminari-views'
-gem 'breadcrumbs_on_rails'
-gem 'bugsnag'
-gem 'cancancan', '3.3.0'
-gem 'cocoon', '~> 1.2'
-gem 'country_select'
-gem 'curation'#, path: '../../arnaudlevy/curation'
-gem 'delayed_job_active_record'
-gem 'delayed_job_web'
-gem 'devise'
-gem 'devise-i18n'
-gem 'enum_help'
-gem 'faceted_search'#, path: '../../noesya/faceted_search'
-gem 'font-awesome-sass'
-gem 'front_matter_parser'
-gem 'gdpr'
-gem 'gitlab'
-gem 'has_scope', '~> 0.8.0'
-gem 'hash_dot'
-gem 'image_processing'
-gem 'jbuilder'
-gem 'jquery-rails'
+gem "activestorage-scaleway-service"#, path: "../activestorage-scaleway-service"
+gem "active_storage_validations", "~> 1.0"
+gem "angularjs-rails"
+gem "aws-sdk-s3"
+gem "bootstrap"
+gem "bootsnap", ">= 1.4.4", require: false
+gem "bootstrap5-kaminari-views"
+gem "breadcrumbs_on_rails"
+gem "bugsnag"
+gem "cancancan", "3.3.0"
+gem "cocoon", "~> 1.2"
+gem "country_select"
+gem "curation"#, path: "../../arnaudlevy/curation"
+gem "delayed_job_active_record"
+gem "delayed_job_web"
+gem "devise"
+gem "devise-i18n"
+gem "enum_help"
+gem "faceted_search"#, path: "../../noesya/faceted_search"
+gem "font-awesome-sass"
+gem "front_matter_parser"
+gem "gdpr"
+gem "gitlab"
+gem "has_scope", "~> 0.8.0"
+gem "hash_dot"
+gem "image_processing"
+gem "jbuilder"
+gem "jquery-rails"
 gem "jquery-ui-rails", "~> 6.0.1"
-gem 'kamifusen'#, path: '../kamifusen'
-gem 'kaminari'
-gem 'mini_magick'
-gem 'octokit'
-gem 'omniauth-rails_csrf_protection', '~> 1.0'
-gem 'omniauth-saml', '~> 2.0'
-gem 'pg', '~> 1.1'
-gem 'puma'
-gem 'rails', '~> 7.0'
+gem "kamifusen"#, path: "../kamifusen"
+gem "kaminari"
+gem "mini_magick"
+gem "octokit"
+gem "omniauth-rails_csrf_protection", "~> 1.0"
+gem "omniauth-saml", "~> 2.0"
+gem "pg", "~> 1.1"
+gem "puma"
+gem "rails", "~> 7.0"
 gem "rails-autocomplete", "~> 2.0"
-gem 'rails-i18n'
-gem 'roo', "~> 2.9"
-gem 'sanitize'
-gem 'sassc-rails'
-# gem 'scout_apm', '~> 5.1'
-gem 'sib-api-v3-sdk'
-gem 'simple-navigation'
-gem 'simple_form'
-gem 'simple_form_bs5_file_input'#, path: '../simple_form_bs5_file_input'
-gem 'simple_form_password_with_hints'#, path: '../simple_form_password_with_hints'
+gem "rails-i18n"
+gem "roo", "~> 2.9"
+gem "sanitize"
+gem "sassc-rails"
+# gem "scout_apm", "~> 5.1"
+gem "sib-api-v3-sdk"
+gem "simple-navigation"
+gem "simple_form"
+gem "simple_form_bs5_file_input"#, path: "../simple_form_bs5_file_input"
+gem "simple_form_password_with_hints"#, path: "../simple_form_password_with_hints"
 gem "sprockets-rails", "~> 3.4"
-gem 'summernote-rails', git: 'https://github.com/noesya/summernote-rails.git', branch: 'activestorage'
-# gem 'summernote-rails', path: '../summernote-rails'
-gem 'two_factor_authentication', git: 'https://github.com/noesya/two_factor_authentication.git'
-# gem 'two_factor_authentication', path: '../two_factor_authentication'
-gem 'unsplash'
+gem "summernote-rails", git: "https://github.com/noesya/summernote-rails.git", branch: "activestorage"
+# gem "summernote-rails", path: "../summernote-rails"
+gem "two_factor_authentication", git: "https://github.com/noesya/two_factor_authentication.git"
+# gem "two_factor_authentication", path: "../two_factor_authentication"
+gem "unsplash"
 
 group :development, :test do
-  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
-  gem 'figaro'
-  gem 'vcr'
-  gem 'webmock'
+  gem "byebug", platforms: [:mri, :mingw, :x64_mingw]
+  gem "figaro"
+  gem "vcr"
+  gem "webmock"
 end
 
 group :development do
-  gem 'annotate'
-  gem 'listen', '~> 3.3'
-  gem 'rack-mini-profiler', '~> 2.0'
-  gem 'spring'
-  gem 'web-console', '>= 4.1.0'
+  gem "annotate"
+  gem "listen", "~> 3.3"
+  gem "rack-mini-profiler", "~> 2.0"
+  gem "spring"
+  gem "web-console", ">= 4.1.0"
 end
 
 group :test do
-  gem 'capybara', '>= 3.26'
-  gem 'selenium-webdriver'
-  gem 'webdrivers'
+  gem "capybara", ">= 3.26"
+  gem "selenium-webdriver"
+  gem "webdrivers"
   gem "simplecov", require: false
 end
 
-gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
+gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
diff --git a/Gemfile.lock b/Gemfile.lock
index f40ffc6b8707e0ae1aa7e2eab102e40576ded353..7bc762f5d2d38bf20f70172f112b20353a54a7f3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -9,7 +9,7 @@ GIT
 
 GIT
   remote: https://github.com/noesya/two_factor_authentication.git
-  revision: ab9734c72d389aefe8ff566d41a0c35bfe5ec989
+  revision: 4574ece65da41397dd852001e22a0c3b9ee3d01e
   specs:
     two_factor_authentication (4.0.0)
       devise
@@ -66,6 +66,11 @@ GEM
       erubi (~> 1.4)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.1, >= 1.2.0)
+    active_storage_validations (1.0.3)
+      activejob (>= 5.2.0)
+      activemodel (>= 5.2.0)
+      activestorage (>= 5.2.0)
+      activesupport (>= 5.2.0)
     activejob (7.0.4)
       activesupport (= 7.0.4)
       globalid (>= 0.3.6)
@@ -98,13 +103,13 @@ GEM
     autoprefixer-rails (10.4.7.0)
       execjs (~> 2)
     aws-eventstream (1.2.0)
-    aws-partitions (1.669.0)
-    aws-sdk-core (3.168.2)
+    aws-partitions (1.688.0)
+    aws-sdk-core (3.168.4)
       aws-eventstream (~> 1, >= 1.0.2)
       aws-partitions (~> 1, >= 1.651.0)
       aws-sigv4 (~> 1.5)
       jmespath (~> 1, >= 1.6.1)
-    aws-sdk-kms (1.60.0)
+    aws-sdk-kms (1.61.0)
       aws-sdk-core (~> 3, >= 3.165.0)
       aws-sigv4 (~> 1.1)
     aws-sdk-s3 (1.117.2)
@@ -126,7 +131,7 @@ GEM
       rails (>= 3.1)
     breadcrumbs_on_rails (4.1.0)
       railties (>= 5.0)
-    bugsnag (6.25.0)
+    bugsnag (6.25.1)
       concurrent-ruby (~> 1.0)
     builder (3.2.4)
     byebug (11.1.3)
@@ -140,12 +145,11 @@ GEM
       rack-test (>= 0.6.3)
       regexp_parser (>= 1.5, < 3.0)
       xpath (~> 3.2)
-    childprocess (4.1.0)
     cocoon (1.2.15)
     concurrent-ruby (1.1.10)
-    countries (5.2.0)
+    countries (5.3.0)
       unaccent (~> 0.3)
-    country_select (8.0.0)
+    country_select (8.0.1)
       countries (~> 5.0)
     crack (0.4.5)
       rexml
@@ -154,6 +158,7 @@ GEM
       htmlentities
       metainspector (~> 5.12)
       nokogiri
+    date (3.3.3)
     delayed_job (4.1.11)
       activesupport (>= 3.0, < 8.0)
     delayed_job_active_record (4.1.7)
@@ -178,14 +183,14 @@ GEM
     encryptor (3.0.0)
     enum_help (0.0.19)
       activesupport (>= 3.0.0)
-    erubi (1.11.0)
+    erubi (1.12.0)
     ethon (0.16.0)
       ffi (>= 1.15.0)
     execjs (2.8.1)
     faceted_search (3.5.16)
       font-awesome-sass
       rails (>= 5.2.0)
-    faraday (2.7.1)
+    faraday (2.7.2)
       faraday-net_http (>= 2.0, < 3.1)
       ruby2_keywords (>= 0.0.4)
     faraday-cookie_jar (0.0.7)
@@ -230,8 +235,8 @@ GEM
     htmlentities (4.3.4)
     http-cookie (1.0.5)
       domain_name (~> 0.5)
-    httparty (0.20.0)
-      mime-types (~> 3.0)
+    httparty (0.21.0)
+      mini_mime (>= 1.0.0)
       multi_xml (>= 0.5.2)
     i18n (1.12.0)
       concurrent-ruby (~> 1.0)
@@ -250,8 +255,8 @@ GEM
       railties (>= 3.2.16)
     js_cookie_rails (2.2.0)
       railties (>= 3.1)
-    json (2.6.2)
-    jwt (2.5.0)
+    json (2.6.3)
+    jwt (2.6.0)
     kamifusen (1.11.2)
       image_processing
       rails
@@ -270,11 +275,14 @@ GEM
     listen (3.7.1)
       rb-fsevent (~> 0.10, >= 0.10.3)
       rb-inotify (~> 0.9, >= 0.9.10)
-    loofah (2.19.0)
+    loofah (2.19.1)
       crass (~> 1.0.2)
       nokogiri (>= 1.5.9)
-    mail (2.7.1)
+    mail (2.8.0)
       mini_mime (>= 0.1.1)
+      net-imap
+      net-pop
+      net-smtp
     marcel (1.0.2)
     matrix (0.4.2)
     metainspector (5.13.1)
@@ -290,32 +298,30 @@ GEM
       nesty (~> 1.0)
       nokogiri (~> 1.13)
     method_source (1.0.0)
-    mime-types (3.4.1)
-      mime-types-data (~> 3.2015)
-    mime-types-data (3.2022.0105)
-    mini_magick (4.11.0)
+    mini_magick (4.12.0)
     mini_mime (1.1.2)
-    minitest (5.16.3)
+    minitest (5.17.0)
     msgpack (1.6.0)
     multi_xml (0.6.0)
     multipart-post (2.2.3)
     mustermann (3.0.0)
       ruby2_keywords (~> 0.0.1)
     nesty (1.0.2)
-    net-imap (0.3.1)
+    net-imap (0.3.4)
+      date
       net-protocol
     net-pop (0.1.2)
       net-protocol
-    net-protocol (0.1.3)
+    net-protocol (0.2.1)
       timeout
     net-smtp (0.3.3)
       net-protocol
     nio4r (2.5.8)
-    nokogiri (1.13.9-arm64-darwin)
+    nokogiri (1.13.10-arm64-darwin)
       racc (~> 1.4)
-    nokogiri (1.13.9-x86_64-darwin)
+    nokogiri (1.13.10-x86_64-darwin)
       racc (~> 1.4)
-    nokogiri (1.13.9-x86_64-linux)
+    nokogiri (1.13.10-x86_64-linux)
       racc (~> 1.4)
     oauth2 (2.0.9)
       faraday (>= 0.17.3, < 3.0)
@@ -340,14 +346,14 @@ GEM
     orm_adapter (0.5.0)
     pg (1.4.5)
     popper_js (2.11.6)
-    public_suffix (5.0.0)
-    puma (6.0.0)
+    public_suffix (5.0.1)
+    puma (6.0.2)
       nio4r (~> 2.0)
-    racc (1.6.0)
-    rack (2.2.4)
+    racc (1.6.2)
+    rack (2.2.5)
     rack-mini-profiler (2.3.4)
       rack (>= 1.2.0)
-    rack-protection (3.0.4)
+    rack-protection (3.0.5)
       rack
     rack-test (2.0.2)
       rack (>= 1.3)
@@ -370,8 +376,8 @@ GEM
     rails-dom-testing (2.0.3)
       activesupport (>= 4.2.0)
       nokogiri (>= 1.6)
-    rails-html-sanitizer (1.4.3)
-      loofah (~> 2.3)
+    rails-html-sanitizer (1.4.4)
+      loofah (~> 2.19, >= 2.19.1)
     rails-i18n (7.0.6)
       i18n (>= 0.7, < 2)
       railties (>= 6.0.0, < 8)
@@ -395,9 +401,9 @@ GEM
     roo (2.9.0)
       nokogiri (~> 1)
       rubyzip (>= 1.3.0, < 3.0.0)
-    rotp (6.2.1)
-    ruby-saml (1.14.0)
-      nokogiri (>= 1.10.5)
+    rotp (6.2.2)
+    ruby-saml (1.15.0)
+      nokogiri (>= 1.13.10)
       rexml
     ruby-vips (2.1.4)
       ffi (~> 1.12)
@@ -417,12 +423,11 @@ GEM
     sawyer (0.9.2)
       addressable (>= 2.3.5)
       faraday (>= 0.17.3, < 3)
-    selenium-webdriver (4.6.1)
-      childprocess (>= 0.5, < 5.0)
+    selenium-webdriver (4.7.1)
       rexml (~> 3.2, >= 3.2.5)
       rubyzip (>= 1.2.2, < 3.0)
       websocket (~> 1.0)
-    sib-api-v3-sdk (9.0.0)
+    sib-api-v3-sdk (9.1.0)
       addressable (~> 2.3, >= 2.3.0)
       json (~> 2.1, >= 2.1.0)
       typhoeus (~> 1.0, >= 1.0.1)
@@ -437,24 +442,24 @@ GEM
     simple_form_password_with_hints (0.0.7)
       rails
       simple_form
-    simplecov (0.21.2)
+    simplecov (0.22.0)
       docile (~> 1.1)
       simplecov-html (~> 0.11)
       simplecov_json_formatter (~> 0.1)
     simplecov-html (0.12.3)
     simplecov_json_formatter (0.1.4)
-    sinatra (3.0.4)
+    sinatra (3.0.5)
       mustermann (~> 3.0)
       rack (~> 2.2, >= 2.2.4)
-      rack-protection (= 3.0.4)
+      rack-protection (= 3.0.5)
       tilt (~> 2.0)
     snaky_hash (2.0.1)
       hashie
       version_gem (~> 1.1, >= 1.1.1)
     spring (4.1.0)
-    sprockets (4.1.1)
+    sprockets (4.2.0)
       concurrent-ruby (~> 1.0)
-      rack (> 1, < 3)
+      rack (>= 2.2.4, < 4)
     sprockets-rails (3.4.2)
       actionpack (>= 5.2)
       activesupport (>= 5.2)
@@ -463,7 +468,7 @@ GEM
       unicode-display_width (>= 1.1.1, < 3)
     thor (1.2.1)
     tilt (2.0.11)
-    timeout (0.3.0)
+    timeout (0.3.1)
     typhoeus (1.4.0)
       ethon (>= 0.9.0)
     tzinfo (2.0.5)
@@ -472,7 +477,7 @@ GEM
     unf (0.1.4)
       unf_ext
     unf_ext (0.0.8.2)
-    unicode-display_width (2.3.0)
+    unicode-display_width (2.4.2)
     unsplash (3.0.0)
       faraday-multipart (~> 1.0.4)
       httparty (~> 0.20)
@@ -511,6 +516,7 @@ PLATFORMS
   x86_64-linux
 
 DEPENDENCIES
+  active_storage_validations (~> 1.0)
   activestorage-scaleway-service
   angularjs-rails
   annotate
diff --git a/app/assets/stylesheets/admin/appstack/style.sass b/app/assets/stylesheets/admin/appstack/style.sass
index 8f70930f8f528c25fceb5695f2c1899b8dc8dcb1..da124eacb9b6cd95671114c41045bf472101ebea 100644
--- a/app/assets/stylesheets/admin/appstack/style.sass
+++ b/app/assets/stylesheets/admin/appstack/style.sass
@@ -38,3 +38,65 @@ main.content
 .sidebar[data-auto-collapsed] + .footer.fixed
     @include media-breakpoint-up(lg)
         left: 0
+
+.invalid-feedback
+    display: block
+
+h1
+    margin-bottom: 30px
+
+.sidebar-nav .fas
+    min-width: 20px
+
+.sidebar
+    background: black
+    footer
+        a
+            padding: 0.625rem 1.625rem
+.sidebar-content
+    background-color: black
+    background-image: asset-url('sun.svg')
+    background-position-x: center
+    background-position-y: -420px
+    background-repeat: no-repeat
+    background-size: 400%
+.sidebar-brand
+    padding: 90px 80px 120px
+.disabled
+    opacity: 0.6
+    pointer-events: none
+.sidebar-link, a.sidebar-link
+    color: rgba(255, 255, 255, 0.8)
+.sidebar-item.active .sidebar-link:hover, .sidebar-item.active > .sidebar-link
+    color: white
+
+#topbar
+    padding-left: $grid-gutter-width
+    padding-right: $grid-gutter-width
+    @include media-breakpoint-up(lg)
+        padding-left: 2.5rem
+        padding-right: 2.5rem
+    .nav-link--last
+        padding-right: 0
+
+.img-circle
+    aspect-ratio: 1/1
+    object-fit: cover
+    width: 100%
+
+.img-fill
+    width: 100%
+
+.card-actions
+    .accordion-button
+        box-shadow: none
+        padding: 0.5rem 0
+
+.draft
+    opacity: 0.5
+
+.btn-light[target=_blank]::after
+    filter: invert(0)
+
+.bg-grey
+    background-color: #DDDDDD !important
\ No newline at end of file
diff --git a/app/assets/stylesheets/admin/appstack/styles.sass b/app/assets/stylesheets/admin/appstack/styles.sass
deleted file mode 100644
index 0a4f09cb38282646f02dfd76cb154ef2b2cf9fbe..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/admin/appstack/styles.sass
+++ /dev/null
@@ -1,58 +0,0 @@
-h1
-    margin-bottom: 30px
-
-.sidebar-nav .fas
-    min-width: 20px
-
-.sidebar
-    background: black
-    footer
-        a
-            padding: 0.625rem 1.625rem
-.sidebar-content
-    background-color: black
-    background-image: asset-url('sun.svg')
-    background-position-x: center
-    background-position-y: -420px
-    background-repeat: no-repeat
-    background-size: 400%
-.sidebar-brand
-    padding: 90px 80px 120px
-.disabled
-    opacity: 0.6
-    pointer-events: none
-.sidebar-link, a.sidebar-link
-    color: rgba(255, 255, 255, 0.8)
-.sidebar-item.active .sidebar-link:hover, .sidebar-item.active > .sidebar-link
-    color: white
-
-#topbar
-    padding-left: $grid-gutter-width
-    padding-right: $grid-gutter-width
-    @include media-breakpoint-up(lg)
-        padding-left: 2.5rem
-        padding-right: 2.5rem
-    .nav-link--last
-        padding-right: 0
-
-.img-circle
-    aspect-ratio: 1/1
-    object-fit: cover
-    width: 100%
-
-.img-fill
-    width: 100%
-
-.card-actions
-    .accordion-button
-        box-shadow: none
-        padding: 0.5rem 0
-
-.draft
-    opacity: 0.5
-
-.btn-light[target=_blank]::after
-    filter: invert(0)
-
-.bg-grey
-    background-color: #DDDDDD !important
\ No newline at end of file
diff --git a/app/models/communication/block.rb b/app/models/communication/block.rb
index bbd8f3b8d36af1bb95a0c1fb99e8d3b27b527776..4b28873c1a4834582c1efc271a31a59cc3bfbd95 100644
--- a/app/models/communication/block.rb
+++ b/app/models/communication/block.rb
@@ -28,6 +28,8 @@ class Communication::Block < ApplicationRecord
   include WithPosition
   include Accessible
 
+  IMAGE_MAX_SIZE = 5.megabytes
+
   belongs_to :about, polymorphic: true
 
   # Used to purge images when unattaching them
diff --git a/app/models/communication/extranet.rb b/app/models/communication/extranet.rb
index e4a52332b9a907f1716fa465a7eea38306c264b1..d48d2a51c9f6cfcc2ed88f03caefa06031441ca4 100644
--- a/app/models/communication/extranet.rb
+++ b/app/models/communication/extranet.rb
@@ -40,13 +40,15 @@ class Communication::Extranet < ApplicationRecord
   include WithSso
   include WithUniversity
 
-  validates_presence_of :name, :host
-
   has_one_attached_deletable :logo
   has_one_attached_deletable :favicon do |attachable|
     attachable.variant :thumb, resize_to_limit: [228, 228]
   end
 
+  validates_presence_of :name, :host
+  validates :logo, size: { less_than: 1.megabytes }
+  validates :favicon, size: { less_than: 1.megabytes }
+
   scope :ordered, -> { order(:name) }
   scope :for_search_term, -> (term) {
     where("
diff --git a/app/models/concerns/with_featured_image.rb b/app/models/concerns/with_featured_image.rb
index 91f13b5938a301e3b5f30bfbac3500c685e514bb..384bf71f1f1841cd362966e6488bb08a3dc8b530 100644
--- a/app/models/concerns/with_featured_image.rb
+++ b/app/models/concerns/with_featured_image.rb
@@ -3,6 +3,8 @@ module WithFeaturedImage
 
   included do
     has_one_attached_deletable :featured_image
+
+    validates :featured_image, size: { less_than: 5.megabytes }
   end
 
   # Can be overwrite to get featured_image from associated objects (ex: parents)
diff --git a/app/models/education/program.rb b/app/models/education/program.rb
index 23a0858aec99e537faa3c03c8457fed2a408c76e..9cfa03597eedbf3c7a38dde7201fb84ff339b4a4 100644
--- a/app/models/education/program.rb
+++ b/app/models/education/program.rb
@@ -95,6 +95,7 @@ class Education::Program < ApplicationRecord
   has_one_attached_deletable :downloadable_summary
 
   validates_presence_of :name
+  validates :downloadable_summary, size: { less_than: 50.megabytes }
 
   after_save :update_children_paths, if: :saved_change_to_path?
 
diff --git a/app/models/education/school.rb b/app/models/education/school.rb
index 0497ecea97f11554307925879ca20ca884c0d261..18c4dcc12f3e5604a8bc9a76a505468fbc4f7076 100644
--- a/app/models/education/school.rb
+++ b/app/models/education/school.rb
@@ -40,6 +40,7 @@ class Education::School < ApplicationRecord
   has_one_attached_deletable :logo
 
   validates :name, :address, :city, :zipcode, :country, presence: true
+  validates :logo, size: { less_than: 1.megabytes }
 
   scope :ordered, -> { order(:name) }
   scope :for_search_term, -> (term) {
diff --git a/app/models/university.rb b/app/models/university.rb
index d839b84370205d64e17a16f550aa6371139ca52f..96f44ec4a8cf892d7a063d72b354b6ab28550507 100644
--- a/app/models/university.rb
+++ b/app/models/university.rb
@@ -48,6 +48,7 @@ class University < ApplicationRecord
 
   validates_presence_of :name
   validates :sms_sender_name, presence: true, length: { maximum: 11 }
+  validates :logo, size: { less_than: 1.megabytes }
 
   after_destroy :destroy_remaining_blobs
 
diff --git a/app/models/university/organization.rb b/app/models/university/organization.rb
index e3119d42a2eaea768a62406ea0abd08e2a4781c5..d135675b09cfc9ab2d57665b9d7e129b95fff5cb 100644
--- a/app/models/university/organization.rb
+++ b/app/models/university/organization.rb
@@ -51,6 +51,13 @@ class University::Organization < ApplicationRecord
   has_one_attached_deletable :logo
   has_one_attached_deletable :logo_on_dark_background
 
+  validates_presence_of :name
+  validates_uniqueness_of :name, scope: :university_id
+  validates :logo, size: { less_than: 1.megabytes }
+  validates :logo_on_dark_background, size: { less_than: 1.megabytes }
+  # Organization can be created from extranet with only their name. Be careful for future validators.
+  # There is an attribute accessor above : `created_from_extranet`
+
   scope :ordered, -> { order(:name) }
   scope :for_kind, -> (kind) { where(kind: kind) }
   scope :for_search_term, -> (term) {
@@ -77,11 +84,6 @@ class University::Organization < ApplicationRecord
     ", term: "%#{sanitize_sql_like(term)}%")
   }
 
-  validates_presence_of :name
-  validates_uniqueness_of :name, scope: :university_id
-  # Organization can be created from extranet with only their name. Be careful for future validators.
-  # There is an attribute accessor above : `created_from_extranet`
-
   enum kind: {
     company: 10,
     non_profit: 20,
diff --git a/app/models/university/person/with_picture.rb b/app/models/university/person/with_picture.rb
index 31be4dd3debe9670fc969cf3cbfded6e9a0138c3..95baa206886e660af6b91b50d34369a0a6053235 100644
--- a/app/models/university/person/with_picture.rb
+++ b/app/models/university/person/with_picture.rb
@@ -3,6 +3,8 @@ module University::Person::WithPicture
 
   included do
     has_one_attached_deletable :picture
+
+    validates :picture, size: { less_than: 5.megabytes }
   end
 
   def best_picture
diff --git a/app/models/user/with_avatar.rb b/app/models/user/with_avatar.rb
index 863b3d0a237145865bfcec2217b67d65d5f1cdec..5f9e0d3dc035f4cef3805b809dd6804526cc2d6e 100644
--- a/app/models/user/with_avatar.rb
+++ b/app/models/user/with_avatar.rb
@@ -4,34 +4,36 @@ module User::WithAvatar
   included do
     has_one_attached_deletable :picture # Nota: user has a picture_url property for SSO mapping. If picture_url is set it will use the url to change the picture
 
+    validates :picture, size: { less_than: 5.megabytes }
+
     before_save :update_picture, if: :will_save_change_to_picture_url?
     after_save :update_picture_url
+  end
 
-    private
+  private
 
-    def update_picture
-      if picture_url.blank?
-        do_purge_picture
-      else
-        do_update_picture
-      end
+  def update_picture
+    if picture_url.blank?
+      do_purge_picture
+    else
+      do_update_picture
     end
+  end
 
-    def update_picture_url
-      if picture_url.present? && !picture.attached?
-        self.update_column(:picture_url, nil)
-      end
+  def update_picture_url
+    if picture_url.present? && !picture.attached?
+      self.update_column(:picture_url, nil)
     end
+  end
 
-    def do_purge_picture
-      self.picture.purge if self.picture.attached?
-    end
+  def do_purge_picture
+    self.picture.purge if self.picture.attached?
+  end
 
-    def do_update_picture
-      downloaded_image = open(picture_url)
-      content_type = downloaded_image.content_type
-      extension = content_type.split('/').last
-      self.picture.attach(io: downloaded_image, filename: "avatar.#{extension}")
-    end
+  def do_update_picture
+    downloaded_image = open(picture_url)
+    content_type = downloaded_image.content_type
+    extension = content_type.split('/').last
+    self.picture.attach(io: downloaded_image, filename: "avatar.#{extension}")
   end
 end
diff --git a/app/views/admin/communication/blocks/edit.html.erb b/app/views/admin/communication/blocks/edit.html.erb
index b37fbbce4fca304a647bede0179c82a769db3831..7ac4162144fff987ede45d0942a1be3c9c06f919 100644
--- a/app/views/admin/communication/blocks/edit.html.erb
+++ b/app/views/admin/communication/blocks/edit.html.erb
@@ -51,7 +51,7 @@
       return {
         directUpload: {
           url: "<%= rails_direct_uploads_url.html_safe %>",
-          blobUrlTemplate: "<%= rails_service_blob_url(":signed_id", ":filename").html_safe %>"
+          blobUrlTemplate: "<%= medium_url(":signed_id", ":filename").html_safe %>"
         },
         data: <%= @block.data.to_json.html_safe %>,
         <% if @element %>
@@ -68,7 +68,12 @@
         this.uploadFile(files[0], object, key);
       },
       uploadFile(file, object, key) {
-        var url = this.directUpload.url;
+        var url = this.directUpload.url,
+            size = Math.round(file.size / 1024 / 1024);
+        if (file.size > <%= Communication::Block::IMAGE_MAX_SIZE %>) {
+          alert("<%= t('admin.communication.blocks.alerts.image_is_too_big').html_safe %> (" + size + " Mo > <%= number_to_human_size Communication::Block::IMAGE_MAX_SIZE %>)");
+          return;
+        }
         var upload = new ActiveStorage.DirectUpload(file, url);
         upload.create(function (error, blob) {
           if (error) {
@@ -88,7 +93,7 @@
           .replace(':filename', filename);
       },
       getImageUrl(data) {
-        return this.getFileUrl(data.signed_id, data.filename);
+        return this.getFileUrl(data.signed_id, "image_1024x.jpg");
       },
       handleSummernotes() {
         var $summernoteElements = $('.summernote-vue');
diff --git a/config/locales/communication/en.yml b/config/locales/communication/en.yml
index 60e65731f66797c9dc4ef7ae9cab043b59198c57..4922963ac56fc45fc3c156bcc6b0a58e3c3ef821 100644
--- a/config/locales/communication/en.yml
+++ b/config/locales/communication/en.yml
@@ -156,6 +156,8 @@ en:
   admin:
     communication:
       blocks:
+        alerts:
+          image_is_too_big: Image is too big!
         categories:
           basic:
             label: Basic blocks
diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml
index 5dde60e92ac9f88b600b77d12e92171c36d503fd..5d056fb340739616c5b431ad689999b31bb27c1e 100644
--- a/config/locales/communication/fr.yml
+++ b/config/locales/communication/fr.yml
@@ -156,6 +156,8 @@ fr:
   admin:
     communication:
       blocks:
+        alerts:
+          image_is_too_big: L'image est trop grosse !
         categories:
           basic:
             label: Blocs de base