Browse Source

Maintenance: Add Content Security Policy.

Thorsten Eckel 5 years ago
parent
commit
49b0ca4d58

+ 4 - 1
app/assets/javascripts/app/controllers/ticket_zoom/article_new.coffee

@@ -132,7 +132,10 @@ class App.TicketZoomArticleNew extends App.Controller
       textRange.select()
 
   isIE10: ->
-    Function('/*@cc_on return document.documentMode===10@*/')()
+    detected = App.Browser.detection()
+    return false if !detected.browser
+    return false if detected.browser.name != 'Explorer'
+    return detected.browser.major == 10
 
   release: =>
     if @subscribeIdTextModule

+ 6 - 1
app/assets/javascripts/app/controllers/ticket_zoom/article_view.coffee

@@ -134,7 +134,12 @@ class ArticleViewItem extends App.ObserverController
     attachments = App.TicketArticle.contentAttachments(article)
     if article.attachments
       for attachment in article.attachments
-        attachment.url = "#{App.Config.get('api_path')}/ticket_attachment/#{article.ticket_id}/#{article.id}/#{attachment.id}?disposition=attachment"
+
+        dispositionParams = ''
+        if attachment?.preferences['Content-Type'] isnt 'application/pdf' && attachment?.preferences['Content-Type'] isnt 'text/html'
+          dispositionParams = '?disposition=attachment'
+
+        attachment.url = "#{App.Config.get('api_path')}/ticket_attachment/#{article.ticket_id}/#{article.id}/#{attachment.id}#{dispositionParams}"
         attachment.preview_url = "#{App.Config.get('api_path')}/ticket_attachment/#{article.ticket_id}/#{article.id}/#{attachment.id}?view=preview"
 
         if attachment && attachment.preferences && attachment.preferences['original-format'] is true

+ 30 - 1
app/assets/javascripts/app/controllers/widget/translation_inline.coffee

@@ -47,6 +47,33 @@ class Widget extends App.Controller
     # enable translation inline
     App.Config.set('translation_inline', true)
 
+    @observer = new MutationObserver((mutations) ->
+
+      mutations.forEach((mutation) ->
+
+        mutation.addedNodes.forEach((addedNode) ->
+
+          $(addedNode).find('span.translation').on('click.translation', (e) ->
+            e.stopPropagation()
+            return false
+          )
+          $(addedNode).find('span.translation').on('keydown.translation', (e) ->
+            e.stopPropagation()
+            return true
+          )
+        )
+
+        mutation.removedNodes.forEach((removedNode) ->
+          $(removedNode).find('span.translation').off('.translation')
+        )
+      )
+    )
+
+    @observer.observe(document.body, {
+      subtree:   true,
+      childList: true,
+    })
+
     # rerender controllers
     App.Event.trigger('ui:rerender')
 
@@ -93,7 +120,9 @@ class Widget extends App.Controller
         element
 
   disable: ->
-    $('body').off('focus.translation blur.translation')
+    @observer.disconnect()
+
+    $('body').off('.translation')
 
     # disable translation inline
     App.Config.set('translation_inline', false)

+ 1 - 1
app/assets/javascripts/app/lib/app_post/i18n.coffee

@@ -247,7 +247,7 @@ class _i18nSingleton extends Spine.Module
     return string if !string
 
     if App.Config.get('translation_inline')
-      return '<span class="translation" onkeydown="arguments[0].stopPropagation(); return true" onclick="arguments[0].stopPropagation(); return false" contenteditable="true" title="' + App.Utils.htmlEscape(string) + '">' + App.Utils.htmlEscape(@translate(string)) + '</span>'
+      return '<span class="translation" contenteditable="true" title="' + App.Utils.htmlEscape(string) + '">' + App.Utils.htmlEscape(@translate(string)) + '</span>'
 
     translated = @translate(string, args, true, true)
 

+ 1 - 0
app/assets/javascripts/app/lib/mixins/view_helpers.coffee

@@ -193,6 +193,7 @@ App.ViewHelpers =
 
   canDownload: (contentType) ->
     contentType = App.Utils.contentTypeCleanup(contentType)
+    return false if contentType is 'application/pdf'
     contentType != 'text/html'
 
   canPreview: (contentType) ->

+ 1 - 0
app/controllers/application_controller.rb

@@ -10,6 +10,7 @@ class ApplicationController < ActionController::Base
   include ApplicationController::HasUser
   include ApplicationController::HasResponseExtentions
   include ApplicationController::PreventsCsrf
+  include ApplicationController::HasSecureContentSecurityPolicyForDownloads
   include ApplicationController::LogsHttpAccess
   include ApplicationController::ChecksAccess
 end

+ 23 - 0
app/controllers/application_controller/has_secure_content_security_policy_for_downloads.rb

@@ -0,0 +1,23 @@
+module ApplicationController::HasSecureContentSecurityPolicyForDownloads
+  extend ActiveSupport::Concern
+
+  included do
+
+    around_action do |_controller, block|
+
+      subscriber = proc do
+        policy = ActionDispatch::ContentSecurityPolicy.new
+        policy.default_src :none
+        policy.plugin_types 'application/pdf'
+
+        request.content_security_policy = policy
+      end
+
+      ActiveSupport::Notifications.subscribed(subscriber, 'send_file.action_controller') do
+        ActiveSupport::Notifications.subscribed(subscriber, 'send_data.action_controller') do
+          block.call
+        end
+      end
+    end
+  end
+end

+ 3 - 3
app/views/init/index.html.erb

@@ -1,5 +1,5 @@
 <!-- svgstore fallback -->
-<script>
+<%= javascript_tag nonce: true do -%>
   /*
     detect if browser is
     - Chrome 14-20
@@ -27,9 +27,9 @@
     xhr.open('get', 'assets/images/icons.svg', true)
     xhr.send()
   })(document)
-</script>
+<% end -%>
 <div id="app"></div>
 <div class="splash">
   <svg class="icon icon-logo"><use xlink:href="assets/images/icons.svg#icon-logo" /></svg>
   <div class="splash-title">Loading...</div>
-</div>
+</div>

+ 2 - 2
app/views/layouts/application.html.erb

@@ -9,9 +9,9 @@
   <%= stylesheet_link_tag "application", :media => 'all' %>
   <%= stylesheet_link_tag "application-print", :media => 'print' %>
   <% if Rails.configuration.assets.debug %>
-  <%= javascript_include_tag "application" %>
+  <%= javascript_include_tag "application", nonce: true %>
   <% else %>
-  <%= javascript_include_tag "application", :defer => 'defer' %>
+  <%= javascript_include_tag "application", nonce: true, :defer => 'defer' %>
   <% end %>
   <%= csrf_meta_tags %>
 </head>

+ 7 - 4
app/views/layouts/knowledge_base.html.erb

@@ -70,10 +70,13 @@
   </footer>
 </div>
 
-<script type='text/javascript'>
+<%= javascript_tag nonce: true do -%>
   if(window.fetch === undefined || window.Promise === undefined || Element.prototype.prepend === undefined){
-    document.write('<script src="<%= path_to_javascript('knowledge_base_public_polyfills') %>"><\/script>')
+    var polyfillScriptTag = document.createElement('script');
+    polyfillScriptTag.setAttribute('src', '<%= path_to_javascript('knowledge_base_public_polyfills') %>');
+    polyfillScriptTag.setAttribute('nonce', '<%= content_security_policy_nonce %>');
+    document.body.appendChild(polyfillScriptTag);
   }
-</script>
+<% end -%>
 
-<%= javascript_include_tag 'knowledge_base_public' %>
+<%= javascript_include_tag 'knowledge_base_public', nonce: true %>

Some files were not shown because too many files changed in this diff