Insert nonces in animation disabler if available

This commit is contained in:
Thomas Walpole 2022-04-30 16:21:07 -07:00
parent 1c164b608f
commit 71770a1b81
3 changed files with 38 additions and 13 deletions

View File

@ -26,9 +26,10 @@ module Capybara
@status, @headers, @body = @app.call(env)
return [@status, @headers, @body] unless html_content?
nonces = directive_nonces.transform_values { |nonce| "nonce=\"#{nonce}\"" if nonce && !nonce.empty? }
response = Rack::Response.new([], @status, @headers)
@body.each { |html| response.write insert_disable(html) }
@body.each { |html| response.write insert_disable(html, nonces) }
@body.close if @body.respond_to?(:close)
response.finish
@ -42,28 +43,35 @@ module Capybara
/html/.match?(@headers['Content-Type'])
end
def insert_disable(html)
html.sub(%r{(</head>)}, "#{disable_css_markup}\\1").sub(%r{(</body>)}, "#{disable_js_markup}\\1")
def insert_disable(html, nonces)
puts nonces
h=html.sub(%r{(</head>)}, "<style #{nonces['style-src']}>#{disable_css_markup}</style>\\1")
.sub(%r{(</body>)}, "<script #{nonces['script-src']}>#{disable_js_markup}</script>\\1")
puts h
h
end
def directive_nonces
@headers.fetch('Content-Security-Policy', '')
.split(';')
.map { |s| s.split(' ') }
.to_h { |s| [s[0], s[1..].filter_map { |value| /^\'nonce-(?<nonce>.+)\'/ =~ value; nonce}[0]]}
end
DISABLE_CSS_MARKUP_TEMPLATE = <<~HTML
<style>
DISABLE_CSS_MARKUP_TEMPLATE = <<~CSS
%<selector>s, %<selector>s::before, %<selector>s::after {
transition: none !important;
animation-duration: 0s !important;
animation-delay: 0s !important;
scroll-behavior: auto !important;
}
</style>
HTML
CSS
DISABLE_JS_MARKUP_TEMPLATE = <<~HTML
<script>
DISABLE_JS_MARKUP_TEMPLATE = <<~SCRIPT
//<![CDATA[
(typeof jQuery !== 'undefined') && (jQuery.fx.off = true);
//]]>
</script>
HTML
SCRIPT
end
end
end

View File

@ -193,6 +193,23 @@ class TestApp < Sinatra::Base
HTML
end
get '/csp' do
response.headers['Content-Security-Policy'] = "default-src 'none'; connect-src 'self'; base-uri 'none'; font-src 'self'; img-src 'self' data:; object-src 'none'; script-src 'self' 'nonce-jAviMuMisoTisVXjgLoWdA=='; style-src 'self' 'nonce-jAviMuMisoTisVXjgLoWdA=='; form-action 'self';"
<<-HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title>CSP</title>
</head>
<body>
<div>CSP</div>
</body>
</html>
HTML
end
get '/download.csv' do
content_type 'text/csv'
'This, is, comma, separated' \
@ -242,7 +259,7 @@ class TestApp < Sinatra::Base
get '/apple-touch-icon-precomposed.png' do
halt(404)
end
class << self
attr_accessor :form_post_count
end

View File

@ -505,7 +505,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
end
end
# rubocop:enable RSpec/InstanceVariable
describe ':element selector' do
it 'can find html5 svg elements' do
session.visit('with_html5_svg')