GithubHelp home page GithubHelp logo

Comments (4)

tannalynn avatar tannalynn commented on July 20, 2024

Hello @viraptor !
Thank you for bringing this issue to our attention. We don't have any current plans around this but we discussed it and thought about a good approach for the agent. We believe the second option makes more sense for us.
We were thinking a path we could take would be to create browser_monitoring_tag, to use similar to javascript_tag. This would allow auto instrumentation to still be enabled for other calls, but would allow individual calls to include options like nonces.
Here is a very rough idea of what type of thing we were thinking about.

require "action_view/helpers/tag_helper"
​
module NewRelic::Agent
  module BrowswerMonitoring #:nodoc:
    module JavaScriptHelper
      #
      #   <%= browser_monitoring_tag nonce: true do -%>
      #     alert('All is good')
      #   <% end -%>
      def browser_monitoring_tag(content_or_options_with_block = nil, html_options = {}, &block)
        ENV["ALREADY_INSTRUMENTED_KEY"] = true
​
        js_to_inject = NewRelic::Agent.browser_timing_header
        content_tag("script", js_to_inject, html_options)
      end
    end
  end
end
​
module ActionView #:nodoc:
  module Helpers #:nodoc:
    include NewRelic::Agent::BrowserMonitoring::JavaScriptHelper
  end
end

Thank you very much for being willing to contribute work for this! Hopefully this will be a helpful direction. If you have any questions that pop up, we are happy to help.
Thanks!

from newrelic-ruby-agent.

eric-hemasystems avatar eric-hemasystems commented on July 20, 2024

I like the strategy here and was able to get it successfully working. I made some technical changes but the concepts it the same as above.

In an Rails initialize file I put:

module NewRelic::JavaScriptHelper
  def new_relic_monitoring_tag
    js = NewRelic::Agent.browser_timing_header
    js.gsub! '<script>', ''
    js.gsub! '</script>', ';'
    javascript_tag js, nonce: true
  end
end

ActiveSupport.on_load(:action_view) { include NewRelic::JavaScriptHelper }
Rails.application.config.middleware.delete NewRelic::Rack::BrowserMonitoring

Then in my application.html.erb I simply have the following right after the head:

<%= new_relic_monitoring_tag %>

Technical notes:

  1. ENV and rack's env hash are not the same. Also the string "ALREADY_INSTRUMENTED_KEY" is being used as the key instead of the constant from the library. I think what was intended should have been request.env[NewRelic::Rack::BrowserMonitoring::ALREADY_INSTRUMENTED_KEY] = true. But I opted instead for just removing the NewRelic middleware with last line in my code. The middleware's only purpose is to inject this content. Rather than manipulate internal flags it seems better to just remove it. Also the middleware generates all the JS then calls should_instrument? to determine if it should inject the JS. This means if the answer is no it just wasted a bunch of work generates that JS. By removing the middleware we skip that work.
  2. I used the on_load hook instead of opening the ActionView::Helpers up. This is the more supported method of extending ActionView.
  3. I removed the arguments for browser_monitoring_tag as the above code doesn't use any of them and we don't need to pass any argument. Also we want to delegate to javascript_tag not content_tag.
  4. Finally I had to strip out the <script> tags as that is already bundled with the return value from browser_timing_header.

from newrelic-ruby-agent.

obenda avatar obenda commented on July 20, 2024

I made the following changes in order to support New Relic gem with CSP

  1. I added the following method as helper - under application_helper.rb
def add_nonce(script)
  raw(script.gsub('<script>',"<script nonce='#{content_security_policy_script_nonce}'>"))
end
  1. I turned off the auto_instrument under newrelic.yml
browser_monitoring:
    auto_instrument: false
  1. I added the following tag under the application main layout - application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <%= add_nonce(::NewRelic::Agent.browser_timing_header) rescue "" %>
    ...
    ...
  1. I added to following domains under the CSP configuration - secure_headers.rb
SecureHeaders::Configuration.default do |config|
  config.csp[:script_src] = %w(...
                               js-agent.newrelic.com
                               bam.nr-data.net)
  ...
end

from newrelic-ruby-agent.

angelatan2 avatar angelatan2 commented on July 20, 2024

@obenda, just a note that we are picking up this issue add support for CSP nonce. We will review your suggestion as well as @eric-hemasystems feedback and the original request from @viraptor.

from newrelic-ruby-agent.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.