Enable Subresource Integrity
This commit is contained in:
@ -8,7 +8,7 @@ module ExerciseHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def qa_js_tag
|
def qa_js_tag
|
||||||
javascript_include_tag "#{qa_url}/assets/qa_api.js"
|
javascript_include_tag "#{qa_url}/assets/qa_api.js", integrity: true, crossorigin: 'anonymous'
|
||||||
end
|
end
|
||||||
|
|
||||||
def qa_url
|
def qa_url
|
||||||
|
@ -9,10 +9,10 @@ html lang="#{I18n.locale || I18n.default_locale}"
|
|||||||
= favicon_link_tag('/favicon.png', type: 'image/png')
|
= favicon_link_tag('/favicon.png', type: 'image/png')
|
||||||
= favicon_link_tag('/favicon.png', rel: 'apple-touch-icon', type: 'image/png')
|
= favicon_link_tag('/favicon.png', rel: 'apple-touch-icon', type: 'image/png')
|
||||||
= action_cable_meta_tag
|
= action_cable_meta_tag
|
||||||
= stylesheet_pack_tag('application', 'stylesheets', media: 'all', 'data-turbolinks-track': true)
|
= stylesheet_pack_tag('application', 'stylesheets', media: 'all', 'data-turbolinks-track': true, integrity: true, crossorigin: 'anonymous')
|
||||||
= stylesheet_link_tag('application', media: 'all', 'data-turbolinks-track': true)
|
= stylesheet_link_tag('application', media: 'all', 'data-turbolinks-track': true, integrity: true, crossorigin: 'anonymous')
|
||||||
= javascript_pack_tag('application', 'data-turbolinks-track': true, defer: false)
|
= javascript_pack_tag('application', 'data-turbolinks-track': true, defer: false, integrity: true, crossorigin: 'anonymous')
|
||||||
= javascript_include_tag('application', 'data-turbolinks-track': true)
|
= javascript_include_tag('application', 'data-turbolinks-track': true, integrity: true, crossorigin: 'anonymous')
|
||||||
= yield(:head)
|
= yield(:head)
|
||||||
= csrf_meta_tags
|
= csrf_meta_tags
|
||||||
= timeago_script_tag nonce: true
|
= timeago_script_tag nonce: true
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
// See the shakacode/shakapacker README and docs directory for advice on customizing your webpackConfig.
|
// See the shakacode/shakapacker README and docs directory for advice on customizing your webpackConfig.
|
||||||
|
|
||||||
const { webpackConfig, merge } = require('shakapacker')
|
const { webpackConfig, config, merge } = require('shakapacker')
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
|
|
||||||
const CompressionPlugin = require("compression-webpack-plugin");
|
const CompressionPlugin = require("compression-webpack-plugin");
|
||||||
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
||||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||||
const TerserPlugin = require("terser-webpack-plugin");
|
const TerserPlugin = require("terser-webpack-plugin");
|
||||||
|
const WebpackAssetsManifest = require('webpack-assets-manifest');
|
||||||
|
const { SubresourceIntegrityPlugin } = require("webpack-subresource-integrity");
|
||||||
|
|
||||||
// Custom ERB loader to disable Spring and prevent crashes
|
// Custom ERB loader to disable Spring and prevent crashes
|
||||||
const erb = require("./loaders/erb");
|
const erb = require("./loaders/erb");
|
||||||
@ -30,7 +32,9 @@ const envConfig = module.exports = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
publicPath: relative_url_root + public_output_path
|
publicPath: relative_url_root + public_output_path,
|
||||||
|
// the following setting is required for SRI to work:
|
||||||
|
crossOriginLoading: 'anonymous',
|
||||||
},
|
},
|
||||||
performance: {
|
performance: {
|
||||||
// Turn off size warnings for large assets
|
// Turn off size warnings for large assets
|
||||||
@ -53,6 +57,15 @@ const envConfig = module.exports = {
|
|||||||
}),
|
}),
|
||||||
new CompressionPlugin(),
|
new CompressionPlugin(),
|
||||||
new MiniCssExtractPlugin(),
|
new MiniCssExtractPlugin(),
|
||||||
|
new SubresourceIntegrityPlugin(),
|
||||||
|
new WebpackAssetsManifest({
|
||||||
|
entrypoints: true,
|
||||||
|
integrity: false,
|
||||||
|
writeToDisk: true,
|
||||||
|
entrypointsUseAssets: true,
|
||||||
|
publicPath: true,
|
||||||
|
output: config.manifestPath,
|
||||||
|
})
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.css', '.ts', '.tsx'],
|
extensions: ['.css', '.ts', '.tsx'],
|
||||||
@ -65,4 +78,8 @@ const envConfig = module.exports = {
|
|||||||
stats: 'minimal',
|
stats: 'minimal',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use the two lines below to remove the original WebpackAssetsManifest and replace it with our custom config.
|
||||||
|
const filteredPlugins = webpackConfig.plugins.filter((plugin) => !(plugin instanceof WebpackAssetsManifest))
|
||||||
|
webpackConfig.plugins = filteredPlugins;
|
||||||
|
|
||||||
module.exports = merge(webpackConfig, envConfig)
|
module.exports = merge(webpackConfig, envConfig)
|
||||||
|
27
lib/webpacker/sri_helper_extensions.rb
Normal file
27
lib/webpacker/sri_helper_extensions.rb
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Webpacker::SriHelperExtensions
|
||||||
|
def stylesheet_link_tag(*sources, **options)
|
||||||
|
tags = sources.map do |stylesheet|
|
||||||
|
if stylesheet.is_a?(Hash)
|
||||||
|
super(stylesheet[:src], options.merge(integrity: stylesheet[:integrity]))
|
||||||
|
else
|
||||||
|
super(stylesheet, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
safe_join(tags)
|
||||||
|
end
|
||||||
|
|
||||||
|
def javascript_include_tag(*sources, **options)
|
||||||
|
tags = sources.map do |javascript|
|
||||||
|
if javascript.is_a?(Hash)
|
||||||
|
super(javascript[:src], options.merge(integrity: javascript[:integrity]))
|
||||||
|
else
|
||||||
|
super(javascript, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
safe_join(tags)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Sprockets::Rails::Helper.prepend(Webpacker::SriHelperExtensions)
|
29
lib/webpacker/sri_manifest_extensions.rb
Normal file
29
lib/webpacker/sri_manifest_extensions.rb
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Webpacker::SriManifestExtensions
|
||||||
|
def lookup(name, pack_type = {})
|
||||||
|
asset = super
|
||||||
|
|
||||||
|
augment_with_integrity asset, pack_type
|
||||||
|
end
|
||||||
|
|
||||||
|
def lookup_pack_with_chunks(name, pack_type = {})
|
||||||
|
assets = super
|
||||||
|
|
||||||
|
assets.map do |asset|
|
||||||
|
augment_with_integrity asset, pack_type
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def augment_with_integrity(asset, _pack_type = {})
|
||||||
|
if asset.respond_to?(:dig) && asset['integrity']
|
||||||
|
{src: asset['src'], integrity: asset['integrity']}
|
||||||
|
elsif asset.respond_to?(:dig)
|
||||||
|
asset['src']
|
||||||
|
else
|
||||||
|
asset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Webpacker::Manifest.prepend(Webpacker::SriManifestExtensions)
|
@ -51,6 +51,7 @@
|
|||||||
"webpack-cli": "^4.10.0",
|
"webpack-cli": "^4.10.0",
|
||||||
"webpack-merge": "^5.8.0",
|
"webpack-merge": "^5.8.0",
|
||||||
"webpack-sources": "^3.2.3",
|
"webpack-sources": "^3.2.3",
|
||||||
|
"webpack-subresource-integrity": "^5.1.0",
|
||||||
"xss": "^1.0.14"
|
"xss": "^1.0.14"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
12
yarn.lock
12
yarn.lock
@ -4199,6 +4199,11 @@ type-is@~1.6.18:
|
|||||||
media-typer "0.3.0"
|
media-typer "0.3.0"
|
||||||
mime-types "~2.1.24"
|
mime-types "~2.1.24"
|
||||||
|
|
||||||
|
typed-assert@^1.0.8:
|
||||||
|
version "1.0.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/typed-assert/-/typed-assert-1.0.9.tgz#8af9d4f93432c4970ec717e3006f33f135b06213"
|
||||||
|
integrity sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==
|
||||||
|
|
||||||
underscore@^1.13.4:
|
underscore@^1.13.4:
|
||||||
version "1.13.4"
|
version "1.13.4"
|
||||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee"
|
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee"
|
||||||
@ -4387,6 +4392,13 @@ webpack-sources@^3.2.3:
|
|||||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
|
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
|
||||||
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
|
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
|
||||||
|
|
||||||
|
webpack-subresource-integrity@^5.1.0:
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz#8b7606b033c6ccac14e684267cb7fb1f5c2a132a"
|
||||||
|
integrity sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==
|
||||||
|
dependencies:
|
||||||
|
typed-assert "^1.0.8"
|
||||||
|
|
||||||
webpack@^5.74.0:
|
webpack@^5.74.0:
|
||||||
version "5.74.0"
|
version "5.74.0"
|
||||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980"
|
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980"
|
||||||
|
Reference in New Issue
Block a user