Skip to content

Commit

Permalink
Update CSP (#1075)
Browse files Browse the repository at this point in the history
* Move style and script into assets

* Move style and script into assets for navbar

* Move error page styles into assets

* wip

* Fix nonce for mirador link

* Fix hero images on landing

* Update google tag script

* Update nonce syntax

* Adds missing stub

* Re enable conditional

* Remove require

* Remove duplicate

* move into head

* Additional nonce

* pull nonce

* Allow unsafe

* Put full text specs in correct contexts and fix duplicate names

* Adjust directives
  • Loading branch information
K8Sewell authored Dec 6, 2024
1 parent 37890c9 commit eee744f
Show file tree
Hide file tree
Showing 17 changed files with 204 additions and 245 deletions.
1 change: 1 addition & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//= require bootstrap
//= require blacklight/blacklight
//= require download_original
//= require header_navbar
//= require show_more


Expand Down
52 changes: 52 additions & 0 deletions app/assets/javascripts/header_navbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// override the addClass method so that a callback can be used
(function($) {
let oldAddClass = $.fn.addClass;
$.fn.addClass = function() {
for (let i in arguments) {
let arg = arguments[i]
if (!!(arg && arg.constructor && arg.call && arg.apply)) {
setTimeout(arg.bind(this))
delete arguments[i]
}
}
return oldAddClass.apply(this, arguments)
}

})(jQuery)

// show and hide the dropdown links properly
$(document).ready(function() {
$('.secondary-nav .nav-link-title').click(function(e) {
const width = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth

$('.secondary-nav .content-yul').addClass('content-show', function() {
const contentBlock = $('.secondary-nav .dropdown.show .menu-block-wrapper')[0]

if (contentBlock) {
if (width >= 1200) {
$('.content-yul').height(contentBlock.offsetHeight + 20)
} else {
// on devices smaller than 1200px wide, only show the item that was clicked on
$('.secondary-nav .dropdown.show .content-yul').height(contentBlock.offsetHeight + 20)
$('.secondary-nav .dropdown:not(.show) .content-yul').height(0)
}
} else {
$('.content-yul').height(0)
}
})
})

$('body').on('click', function(e) {
if (
!$(e.target).is('.secondary-nav .nav-link-title') && !$(e.target).is('.secondary-nav .nav-link-title li a')||
$(e.target).is('.sort-dropdown') ||
$(e.target).is('.per-page-dropdown')
) {
$('.secondary-nav .content-yul').removeClass('content-show')
$('.content-yul').height(0)
}
})
})

51 changes: 51 additions & 0 deletions app/assets/stylesheets/customOverrides/error_pages.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/********************************************************
DEFAULT MOBILE STYLING
********************************************************/

.rails-default-error-page {
background-color: #EFEFEF;
color: #2E2F30;
text-align: center;
font-family: arial, sans-serif;
margin: 0;
}

.rails-default-error-page div.dialog {
width: 95%;
max-width: 33em;
margin: 4em auto 0;
}

.rails-default-error-page div.dialog > div {
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
border-bottom-color: #BBB;
border-top: #B00100 solid 4px;
border-top-left-radius: 9px;
border-top-right-radius: 9px;
background-color: white;
padding: 7px 12% 0;
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}

.rails-default-error-page h1 {
font-size: 100%;
color: #730E15;
line-height: 1.5em;
}

.rails-default-error-page div.dialog > p {
margin: 0 0 1em;
padding: 1em;
background-color: #F7F7F7;
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
border-bottom-color: #999;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-top-color: #DADADA;
color: #666;
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
1 change: 1 addition & 0 deletions app/assets/stylesheets/customOverrides/header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ DEFAULT MOBILE STYLING
}

.nav-link-caret {
cursor: pointer;
transform: rotate(180deg);
-ms-transform: rotate(180deg); /* for IE */
-webkit-transform: rotate(180deg); /* for browsers supporting webkit (such as chrome, firefox, safari etc.). */
Expand Down
9 changes: 5 additions & 4 deletions app/views/application/landing.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@
</body>
<% end %>

<script>
$(document).ready(function() {
<script nonce="<%= content_security_policy_nonce %>">

$(document).ready(function() {
const images = [
{
alt: 'Conference attendees at "Camp Spingarn," Amenia, N.Y., August 24-26, 1916',
Expand Down Expand Up @@ -163,5 +164,5 @@

$('#hero-image').attr({ 'src': src, 'alt': alt });
$('#hero-image-caption').text(caption);
})
</script>
})
</script>
2 changes: 1 addition & 1 deletion app/views/catalog/_grouped_metadata.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
</div>

<% if @permission_set_terms.present? %>
<script>
<script nonce="<%= content_security_policy_nonce %>">
let rights = document.querySelector('dd.blacklight-rights_ssim');

function expandText() {
Expand Down
2 changes: 1 addition & 1 deletion app/views/catalog/_schema_org_metadata.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<script type="application/ld+json">
<script type="application/ld+json" nonce="<%= content_security_policy_nonce %>">
<%= raw metadata.to_json %>
</script>
2 changes: 1 addition & 1 deletion app/views/catalog/_uv.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<div id='uv-pages'></div>
<div id='parent-oid'><%= @document.id %></div>

<script>
<script nonce="<%= content_security_policy_nonce %>">
$(document).ready(function(){
window.addEventListener('message', (event) => {
if (event.origin.match('<%= request.protocol %><%= request.host %>')) {
Expand Down
41 changes: 21 additions & 20 deletions app/views/mirador/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,36 @@
<%= render partial: 'shared/ga_header' %>
<title>Yale Digital Collections Mirador Viewer</title>
<meta name="robots" content="noindex"/>
<script src="/mirador.js"></script>
<script src="/mirador.js" nonce="<%= content_security_policy_nonce %>"></script>
</head>
<body>
<%= render partial: 'shared/ga_body' %>
<div id="my-mirador"/>
<script type="text/javascript">

<script type="text/javascript" nonce="<%= content_security_policy_nonce %>">
let dc_mirador_config = {
"id": "my-mirador"
}

<% if @manifest %>
const manifest = "<%= @manifest %>";
dc_mirador_config = {
...dc_mirador_config,
"manifests": {
manifest: {
"provider": "Yale University"
}
},
"windows": [
{
"loadedManifest": manifest,
"thumbnailNavigationPosition": 'far-bottom'
}
]
}
<% end %>
<% if @manifest %>
const manifest = "<%= @manifest %>";
dc_mirador_config = {
...dc_mirador_config,
"manifests": {
manifest: {
"provider": "Yale University"
}
},
"windows": [
{
"loadedManifest": manifest,
"thumbnailNavigationPosition": 'far-bottom'
}
]
}
<% end %>

var mirador = Mirador.viewer(dc_mirador_config);
var mirador = Mirador.viewer(dc_mirador_config);
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion app/views/permission_requests/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<% end %>
</div>

<script>
<script nonce="<%= content_security_policy_nonce %>">
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("permission-requests-table");
Expand Down
2 changes: 1 addition & 1 deletion app/views/shared/_footer.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
</div>
</div>
</div>
<aside>
<aside nonce="<%= content_security_policy_nonce %>">
<div class="branch-name">
Branch:<span title="SHA:<%=GIT_SHA%>"><%=ENV['BLACKLIGHT_VERSION']||GIT_BRANCH%></span>,Deployed:<%=DEPLOYED_AT%>
</div>
Expand Down
8 changes: 5 additions & 3 deletions app/views/shared/_ga_header.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
<script nonce="<%= request.content_security_policy_nonce %>">
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-PX75HSF');</script>
<!-- End Google Tag Manager -->
})(window,document,'script','dataLayer','GTM-PX75HSF')
</script>
<!-- End Google Tag Manager -->
62 changes: 4 additions & 58 deletions app/views/shared/_header_navbar.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<div class="dropdown">
<h2 class="nav-link-title" data-toggle="dropdown">
<a href="#" role="button" aria-expanded="true">Research</a>
<p class="nav-link-caret" style="cursor: pointer">
<p class="nav-link-caret">
<%= image_tag("header/2x-angle-up-solid.png", {id: 'research-collapse-nav-bar', alt: 'collapse nav bar'})%>
</p>
</h2>
Expand Down Expand Up @@ -95,7 +95,7 @@
<div class="dropdown">
<h2 class="nav-link-title" data-toggle="dropdown">
<a href="#" role="button" aria-expanded="false">Services</a>
<p class="nav-link-caret" style="cursor: pointer">
<p class="nav-link-caret">
<%= image_tag("header/2x-angle-up-solid.png", {id: 'services-collapse-nav-bar', alt: 'collapse nav bar'})%>
</p>
</h2>
Expand Down Expand Up @@ -167,7 +167,7 @@
<div class="dropdown">
<h2 class="nav-link-title" data-toggle="dropdown">
<a href="#" role="button" aria-expanded="false">Libraries & Collections</a>
<p class="nav-link-caret" style="cursor: pointer">
<p class="nav-link-caret">
<%= image_tag("header/2x-angle-up-solid.png", {id: 'libraries-collapse-nav-bar', alt: 'collapse nav bar'})%>
</p>
</h2>
Expand Down Expand Up @@ -279,7 +279,7 @@
<div class="dropdown">
<h2 class="nav-link-title" data-toggle="dropdown">
<a href="#" role="button" aria-expanded="false">Information & Policies</a>
<p class="nav-link-caret" style="cursor: pointer">
<p class="nav-link-caret">
<%= image_tag("header/2x-angle-up-solid.png", {id: 'info-collapse-nav-bar', alt: 'collapse nav bar'})%>
</p>
</h2>
Expand Down Expand Up @@ -360,57 +360,3 @@
</div>
</div>
</div>

<script>
// override the addClass method so that a callback can be used
(function($) {
let oldAddClass = $.fn.addClass;
$.fn.addClass = function() {
for (let i in arguments) {
let arg = arguments[i]
if (!!(arg && arg.constructor && arg.call && arg.apply)) {
setTimeout(arg.bind(this))
delete arguments[i]
}
}
return oldAddClass.apply(this, arguments)
}

})(jQuery)

// show and hide the dropdown links properly
$(document).ready(function() {
$('.secondary-nav .nav-link-title').click(function(e) {
const width = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth

$('.secondary-nav .content-yul').addClass('content-show', function() {
const contentBlock = $('.secondary-nav .dropdown.show .menu-block-wrapper')[0]

if (contentBlock) {
if (width >= 1200) {
$('.content-yul').height(contentBlock.offsetHeight + 20)
} else {
// on devices smaller than 1200px wide, only show the item that was clicked on
$('.secondary-nav .dropdown.show .content-yul').height(contentBlock.offsetHeight + 20)
$('.secondary-nav .dropdown:not(.show) .content-yul').height(0)
}
} else {
$('.content-yul').height(0)
}
})
})

$('body').on('click', function(e) {
if (
!$(e.target).is('.secondary-nav .nav-link-title') && !$(e.target).is('.secondary-nav .nav-link-title li a')||
$(e.target).is('.sort-dropdown') ||
$(e.target).is('.per-page-dropdown')
) {
$('.secondary-nav .content-yul').removeClass('content-show')
$('.content-yul').height(0)
}
})
})
</script>
14 changes: 9 additions & 5 deletions config/initializers/content_security_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
config.content_security_policy do |policy|
policy.default_src :self, :https
policy.font_src :self, 'static.library.yale.edu'
policy.img_src :self, :https, :data
policy.img_src :self, :https, :data, "#{ENV['IIIF_IMAGE_BASE_URL']}/"
policy.object_src :none
policy.script_src :self, 'siteimproveanalytics.com'
policy.style_src :self
policy.connect_src :self
policy.script_src :self, :unsafe_inline, 'siteimproveanalytics.com www.googletagmanager.com'
policy.script_src_attr :self, :unsafe_inline, 'www.googletagmanager.com'
policy.script_src_elem :self, :unsafe_inline, 'siteimproveanalytics.com www.googletagmanager.com'
policy.style_src :self, :unsafe_inline
policy.style_src_elem :self, :unsafe_inline, "#{ENV['IIIF_IMAGE_BASE_URL']}/"
policy.connect_src :self, "banner.library.yale.edu www.google-analytics.com #{ENV['IIIF_IMAGE_BASE_URL']}/"

# Specify URI for violation reports
unless ENV['CLUSTER_NAME'] == 'local'
policy.report_uri lambda {
Expand All @@ -24,7 +28,7 @@

config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }

config.content_security_policy_nonce_directives = %w[script-src style-src]
# config.content_security_policy_nonce_directives = %w[script-src script-src-attr script-src-elem style-src]

# Report violations without enforcing the policy.
# config.content_security_policy_report_only = true
Expand Down
Loading

0 comments on commit eee744f

Please sign in to comment.