about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2020-11-06 11:56:31 +0100
committerGitHub <noreply@github.com>2020-11-06 11:56:31 +0100
commit9b1f2a4b61660f9a8be62f6296d97a856e376059 (patch)
treedd60029f03394a924d7168277582f0e6c835a9a1
parent68d4b2b83e124719f8473489ee8c1743ca848dc4 (diff)
Add subresource integrity for JS and CSS assets (#15096)
Fix #2744
-rw-r--r--app/views/about/more.html.haml2
-rw-r--r--app/views/admin/action_logs/index.html.haml2
-rw-r--r--app/views/admin/custom_emojis/index.html.haml2
-rw-r--r--app/views/admin/domain_allows/new.html.haml2
-rw-r--r--app/views/admin/domain_blocks/edit.html.haml2
-rw-r--r--app/views/admin/domain_blocks/new.html.haml2
-rw-r--r--app/views/admin/ip_blocks/index.html.haml2
-rw-r--r--app/views/admin/pending_accounts/index.html.haml2
-rw-r--r--app/views/admin/reports/show.html.haml2
-rw-r--r--app/views/admin/settings/edit.html.haml2
-rw-r--r--app/views/admin/statuses/index.html.haml2
-rw-r--r--app/views/admin/tags/index.html.haml2
-rw-r--r--app/views/auth/sessions/two_factor.html.haml2
-rw-r--r--app/views/home/index.html.haml10
-rw-r--r--app/views/layouts/admin.html.haml2
-rwxr-xr-xapp/views/layouts/application.html.haml8
-rw-r--r--app/views/layouts/auth.html.haml2
-rw-r--r--app/views/layouts/embedded.html.haml4
-rw-r--r--app/views/layouts/error.html.haml8
-rw-r--r--app/views/layouts/modal.html.haml2
-rw-r--r--app/views/layouts/public.html.haml2
-rw-r--r--app/views/media/player.html.haml2
-rw-r--r--app/views/public_timelines/show.html.haml2
-rw-r--r--app/views/relationships/show.html.haml2
-rw-r--r--app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml2
-rw-r--r--app/views/shares/show.html.haml2
-rw-r--r--app/views/tags/show.html.haml2
-rw-r--r--config/application.rb2
-rw-r--r--config/webpack/shared.js3
-rw-r--r--lib/webpacker/helper_extensions.rb20
-rw-r--r--lib/webpacker/manifest_extensions.rb17
31 files changed, 79 insertions, 39 deletions
diff --git a/app/views/about/more.html.haml b/app/views/about/more.html.haml
index 4152a3601..c2168e1f5 100644
--- a/app/views/about/more.html.haml
+++ b/app/views/about/more.html.haml
@@ -2,7 +2,7 @@
   = site_hostname
 
 - content_for :header_tags do
-  = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'public', crossorigin: 'anonymous'
   = render partial: 'shared/og'
 
 .grid-4
diff --git a/app/views/admin/action_logs/index.html.haml b/app/views/admin/action_logs/index.html.haml
index 99f756762..e7d9054d9 100644
--- a/app/views/admin/action_logs/index.html.haml
+++ b/app/views/admin/action_logs/index.html.haml
@@ -2,7 +2,7 @@
   = t('admin.action_logs.title')
 
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 = form_tag admin_action_logs_url, method: 'GET', class: 'simple_form' do
   = hidden_field_tag :target_account_id, params[:target_account_id] if params[:target_account_id].present?
diff --git a/app/views/admin/custom_emojis/index.html.haml b/app/views/admin/custom_emojis/index.html.haml
index 1cbc36f97..bfec0407e 100644
--- a/app/views/admin/custom_emojis/index.html.haml
+++ b/app/views/admin/custom_emojis/index.html.haml
@@ -2,7 +2,7 @@
   = t('admin.custom_emojis.title')
 
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 - if can?(:create, :custom_emoji)
   - content_for :heading_actions do
diff --git a/app/views/admin/domain_allows/new.html.haml b/app/views/admin/domain_allows/new.html.haml
index 52599857a..249a961ce 100644
--- a/app/views/admin/domain_allows/new.html.haml
+++ b/app/views/admin/domain_allows/new.html.haml
@@ -1,5 +1,5 @@
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 - content_for :page_title do
   = t('admin.domain_allows.add_new')
diff --git a/app/views/admin/domain_blocks/edit.html.haml b/app/views/admin/domain_blocks/edit.html.haml
index 29e47ef3b..d5868070a 100644
--- a/app/views/admin/domain_blocks/edit.html.haml
+++ b/app/views/admin/domain_blocks/edit.html.haml
@@ -1,5 +1,5 @@
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 - content_for :page_title do
   = t('admin.domain_blocks.edit')
diff --git a/app/views/admin/domain_blocks/new.html.haml b/app/views/admin/domain_blocks/new.html.haml
index ed1581936..f503f9b77 100644
--- a/app/views/admin/domain_blocks/new.html.haml
+++ b/app/views/admin/domain_blocks/new.html.haml
@@ -1,5 +1,5 @@
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 - content_for :page_title do
   = t('.title')
diff --git a/app/views/admin/ip_blocks/index.html.haml b/app/views/admin/ip_blocks/index.html.haml
index a282a4cfe..d5b983de9 100644
--- a/app/views/admin/ip_blocks/index.html.haml
+++ b/app/views/admin/ip_blocks/index.html.haml
@@ -2,7 +2,7 @@
   = t('admin.ip_blocks.title')
 
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 - if can?(:create, :ip_block)
   - content_for :heading_actions do
diff --git a/app/views/admin/pending_accounts/index.html.haml b/app/views/admin/pending_accounts/index.html.haml
index 79ae4a320..8384a1c9f 100644
--- a/app/views/admin/pending_accounts/index.html.haml
+++ b/app/views/admin/pending_accounts/index.html.haml
@@ -2,7 +2,7 @@
   = t('admin.pending_accounts.title', count: User.pending.count)
 
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 = form_for(@form, url: batch_admin_pending_accounts_path) do |f|
   = hidden_field_tag :page, params[:page] || 1
diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml
index 0d563eea7..2681419ca 100644
--- a/app/views/admin/reports/show.html.haml
+++ b/app/views/admin/reports/show.html.haml
@@ -1,5 +1,5 @@
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 - content_for :page_title do
   = t('admin.reports.report', id: @report.id)
diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml
index f37775aa9..9e28766b1 100644
--- a/app/views/admin/settings/edit.html.haml
+++ b/app/views/admin/settings/edit.html.haml
@@ -1,5 +1,5 @@
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 - content_for :page_title do
   = t('admin.settings.title')
diff --git a/app/views/admin/statuses/index.html.haml b/app/views/admin/statuses/index.html.haml
index f1169a2fd..c39ba9071 100644
--- a/app/views/admin/statuses/index.html.haml
+++ b/app/views/admin/statuses/index.html.haml
@@ -1,5 +1,5 @@
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 - content_for :page_title do
   = t('admin.statuses.title')
diff --git a/app/views/admin/tags/index.html.haml b/app/views/admin/tags/index.html.haml
index f888a311d..d7719d45d 100644
--- a/app/views/admin/tags/index.html.haml
+++ b/app/views/admin/tags/index.html.haml
@@ -2,7 +2,7 @@
   = t('admin.tags.title')
 
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 .filters
   .filter-subset
diff --git a/app/views/auth/sessions/two_factor.html.haml b/app/views/auth/sessions/two_factor.html.haml
index f2f6fe19d..b897a0422 100644
--- a/app/views/auth/sessions/two_factor.html.haml
+++ b/app/views/auth/sessions/two_factor.html.haml
@@ -1,7 +1,7 @@
 - content_for :page_title do
   = t('auth.login')
 
-=javascript_pack_tag 'two_factor_authentication', integrity: true, crossorigin: 'anonymous'
+=javascript_pack_tag 'two_factor_authentication', crossorigin: 'anonymous'
 
 - if @webauthn_enabled
   = render partial: 'auth/sessions/two_factor/webauthn_form', locals: { hidden: @scheme_type != 'webauthn' }
diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml
index 30c7aab19..94cc782b2 100644
--- a/app/views/home/index.html.haml
+++ b/app/views/home/index.html.haml
@@ -1,12 +1,12 @@
 - content_for :header_tags do
-  = preload_link_tag asset_pack_path('features/getting_started.js'), crossorigin: 'anonymous'
-  = preload_link_tag asset_pack_path('features/compose.js'), crossorigin: 'anonymous'
-  = preload_link_tag asset_pack_path('features/home_timeline.js'), crossorigin: 'anonymous'
-  = preload_link_tag asset_pack_path('features/notifications.js'), crossorigin: 'anonymous'
+  = preload_pack_asset 'features/getting_started.js', crossorigin: 'anonymous'
+  = preload_pack_asset 'features/compose.js', crossorigin: 'anonymous'
+  = preload_pack_asset 'features/home_timeline.js', crossorigin: 'anonymous'
+  = preload_pack_asset 'features/notifications.js', crossorigin: 'anonymous'
 
   %meta{name: 'applicationServerKey', content: Rails.configuration.x.vapid_public_key}
   = render_initial_state
-  = javascript_pack_tag 'application', integrity: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'application', crossorigin: 'anonymous'
 
 .app-holder#mastodon{ data: { props: Oj.dump(default_props) } }
   %noscript
diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
index b1a2d0617..62716ab1e 100644
--- a/app/views/layouts/admin.html.haml
+++ b/app/views/layouts/admin.html.haml
@@ -1,6 +1,6 @@
 - content_for :header_tags do
   = render_initial_state
-  = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'public', crossorigin: 'anonymous'
 
 - content_for :content do
   .admin-wrapper
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 1f10f40c0..9501207e0 100755
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -21,10 +21,10 @@
 
     %title= content_for?(:page_title) ? safe_join([yield(:page_title).chomp.html_safe, title], ' - ') : title
 
-    = stylesheet_pack_tag 'common', media: 'all'
-    = stylesheet_pack_tag current_theme, media: 'all'
-    = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous'
-    = javascript_pack_tag "locale_#{I18n.locale}", integrity: true, crossorigin: 'anonymous'
+    = stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous'
+    = stylesheet_pack_tag current_theme, media: 'all', crossorigin: 'anonymous'
+    = javascript_pack_tag 'common', crossorigin: 'anonymous'
+    = javascript_pack_tag "locale_#{I18n.locale}", crossorigin: 'anonymous'
     = csrf_meta_tags
     %meta{ name: 'style-nonce', content: request.content_security_policy_nonce }
 
diff --git a/app/views/layouts/auth.html.haml b/app/views/layouts/auth.html.haml
index 585e24655..0ea3bbe3b 100644
--- a/app/views/layouts/auth.html.haml
+++ b/app/views/layouts/auth.html.haml
@@ -1,5 +1,5 @@
 - content_for :header_tags do
-  = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'public', crossorigin: 'anonymous'
 
 - content_for :content do
   .container-alt
diff --git a/app/views/layouts/embedded.html.haml b/app/views/layouts/embedded.html.haml
index 37051e70c..e4311d342 100644
--- a/app/views/layouts/embedded.html.haml
+++ b/app/views/layouts/embedded.html.haml
@@ -11,8 +11,8 @@
     - if storage_host?
       %link{ rel: 'dns-prefetch', href: storage_host }/
 
-    = stylesheet_pack_tag 'common', media: 'all'
-    = stylesheet_pack_tag Setting.default_settings['theme'], media: 'all'
+    = stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous'
+    = stylesheet_pack_tag Setting.default_settings['theme'], media: 'all', crossorigin: 'anonymous'
     = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous'
     = javascript_pack_tag "locale_#{I18n.locale}", integrity: true, crossorigin: 'anonymous'
     = render_initial_state
diff --git a/app/views/layouts/error.html.haml b/app/views/layouts/error.html.haml
index 25c85abf9..852a0c69b 100644
--- a/app/views/layouts/error.html.haml
+++ b/app/views/layouts/error.html.haml
@@ -5,10 +5,10 @@
     %meta{ charset: 'utf-8' }/
     %title= safe_join([yield(:page_title), Setting.default_settings['site_title']], ' - ')
     %meta{ content: 'width=device-width,initial-scale=1', name: 'viewport' }/
-    = stylesheet_pack_tag 'common', media: 'all'
-    = stylesheet_pack_tag Setting.default_settings['theme'], media: 'all'
-    = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous'
-    = javascript_pack_tag 'error', integrity: true, crossorigin: 'anonymous'
+    = stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous'
+    = stylesheet_pack_tag Setting.default_settings['theme'], media: 'all', crossorigin: 'anonymous'
+    = javascript_pack_tag 'common', crossorigin: 'anonymous'
+    = javascript_pack_tag 'error', crossorigin: 'anonymous'
   %body.error
     .dialog
       .dialog__illustration
diff --git a/app/views/layouts/modal.html.haml b/app/views/layouts/modal.html.haml
index 2ef49e413..e74e2c0e3 100644
--- a/app/views/layouts/modal.html.haml
+++ b/app/views/layouts/modal.html.haml
@@ -1,5 +1,5 @@
 - content_for :header_tags do
-  = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'public', crossorigin: 'anonymous'
 
 - content_for :content do
   - if user_signed_in? && !@hide_header
diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml
index a2c4e5deb..e63cf0848 100644
--- a/app/views/layouts/public.html.haml
+++ b/app/views/layouts/public.html.haml
@@ -1,6 +1,6 @@
 - content_for :header_tags do
   = render_initial_state
-  = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'public', crossorigin: 'anonymous'
 
 - content_for :content do
   .public-layout
diff --git a/app/views/media/player.html.haml b/app/views/media/player.html.haml
index ae47750e9..92428ca94 100644
--- a/app/views/media/player.html.haml
+++ b/app/views/media/player.html.haml
@@ -1,6 +1,6 @@
 - content_for :header_tags do
   = render_initial_state
-  = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'public', crossorigin: 'anonymous'
 
 - if @media_attachment.video?
   = react_component :video, src: @media_attachment.file.url(:original), preview: @media_attachment.thumbnail.present? ? @media_attachment.thumbnail.url : @media_attachment.file.url(:small), blurhash: @media_attachment.blurhash, width: 670, height: 380, editable: true, detailed: true, inline: true, alt: @media_attachment.description do
diff --git a/app/views/public_timelines/show.html.haml b/app/views/public_timelines/show.html.haml
index 5e536a235..3325be5bf 100644
--- a/app/views/public_timelines/show.html.haml
+++ b/app/views/public_timelines/show.html.haml
@@ -3,7 +3,7 @@
 
 - content_for :header_tags do
   %meta{ name: 'robots', content: 'noindex' }/
-  = javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'about', crossorigin: 'anonymous'
 
 .page-header
   %h1= t('about.see_whats_happening')
diff --git a/app/views/relationships/show.html.haml b/app/views/relationships/show.html.haml
index 099bb3202..4b1e4fd63 100644
--- a/app/views/relationships/show.html.haml
+++ b/app/views/relationships/show.html.haml
@@ -2,7 +2,7 @@
   = t('settings.relationships')
 
 - content_for :header_tags do
-  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
 
 .filters
   .filter-subset
diff --git a/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml b/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml
index 0b23bb689..1148d5ed7 100644
--- a/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml
+++ b/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml
@@ -13,4 +13,4 @@
   .actions
     = f.button :button, t('webauthn_credentials.add'), class: 'js-webauthn', type: :submit
 
-= javascript_pack_tag 'two_factor_authentication', integrity: true, crossorigin: 'anonymous'
+= javascript_pack_tag 'two_factor_authentication', crossorigin: 'anonymous'
diff --git a/app/views/shares/show.html.haml b/app/views/shares/show.html.haml
index f2f5479a7..1c0bbf676 100644
--- a/app/views/shares/show.html.haml
+++ b/app/views/shares/show.html.haml
@@ -1,5 +1,5 @@
 - content_for :header_tags do
   = render_initial_state
-  = javascript_pack_tag 'share', integrity: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'share', crossorigin: 'anonymous'
 
 #mastodon-compose{ data: { props: Oj.dump(default_props) } }
diff --git a/app/views/tags/show.html.haml b/app/views/tags/show.html.haml
index 19dadd36a..beeeb56f2 100644
--- a/app/views/tags/show.html.haml
+++ b/app/views/tags/show.html.haml
@@ -5,7 +5,7 @@
   %meta{ name: 'robots', content: 'noindex' }/
   %link{ rel: 'alternate', type: 'application/rss+xml', href: tag_url(@tag, format: 'rss') }/
 
-  = javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous'
+  = javascript_pack_tag 'about', crossorigin: 'anonymous'
   = render 'og'
 
 .page-header
diff --git a/config/application.rb b/config/application.rb
index ad6cf82d7..bf467d6c3 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -22,6 +22,8 @@ require_relative '../lib/mastodon/version'
 require_relative '../lib/devise/two_factor_ldap_authenticatable'
 require_relative '../lib/devise/two_factor_pam_authenticatable'
 require_relative '../lib/chewy/strategy/custom_sidekiq'
+require_relative '../lib/webpacker/manifest_extensions'
+require_relative '../lib/webpacker/helper_extensions'
 
 Dotenv::Railtie.load
 
diff --git a/config/webpack/shared.js b/config/webpack/shared.js
index 667652809..05828aebe 100644
--- a/config/webpack/shared.js
+++ b/config/webpack/shared.js
@@ -79,7 +79,8 @@ module.exports = {
       chunkFilename: 'css/[name]-[contenthash:8].chunk.css',
     }),
     new AssetsManifestPlugin({
-      integrity: false,
+      integrity: true,
+      integrityHashes: ['sha256'],
       entrypoints: true,
       writeToDisk: true,
       publicPath: true,
diff --git a/lib/webpacker/helper_extensions.rb b/lib/webpacker/helper_extensions.rb
new file mode 100644
index 000000000..8f46d7631
--- /dev/null
+++ b/lib/webpacker/helper_extensions.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Webpacker::HelperExtensions
+  def javascript_pack_tag(name, **options)
+    src, integrity = current_webpacker_instance.manifest.lookup!(name, type: :javascript, with_integrity: true)
+    javascript_include_tag(src, options.merge(integrity: integrity))
+  end
+
+  def stylesheet_pack_tag(name, **options)
+    src, integrity = current_webpacker_instance.manifest.lookup!(name, type: :stylesheet, with_integrity: true)
+    stylesheet_link_tag(src, options.merge(integrity: integrity))
+  end
+
+  def preload_pack_asset(name, **options)
+    src, integrity = current_webpacker_instance.manifest.lookup!(name, with_integrity: true)
+    preload_link_tag(src, options.merge(integrity: integrity))
+  end
+end
+
+Webpacker::Helper.prepend(Webpacker::HelperExtensions)
diff --git a/lib/webpacker/manifest_extensions.rb b/lib/webpacker/manifest_extensions.rb
new file mode 100644
index 000000000..789eb81cc
--- /dev/null
+++ b/lib/webpacker/manifest_extensions.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Webpacker::ManifestExtensions
+  def lookup(name, pack_type = {})
+    asset = super
+
+    if pack_type[:with_integrity] && asset.respond_to?(:dig)
+      [asset.dig('src'), asset.dig('integrity')]
+    elsif asset.respond_to?(:dig)
+      asset.dig('src')
+    else
+      asset
+    end
+  end
+end
+
+Webpacker::Manifest.prepend(Webpacker::ManifestExtensions)