Your data. Anywhere you go.

New Relic for iOS or Android


Download on the App Store    Android App on Google play


New Relic Insights App for iOS


Download on the App Store


Learn more

Close icon

Best way to add CSP nonce to ::NewRelic::Agent.browser_timing_header


#1

Based on https://docs.newrelic.com/docs/browser/new-relic-browser/getting-started/compatibility-requirements-new-relic-browser

Content-Security-Policy: default-src 'self' https://js-agent.newrelic.com https://bam.nr-data.net

It says to just put both https://js-agent.newrelic.com and https://bam.nr-data.net under default-src for Content-Security-Policy in which we want to be more specific and not just blindly let everything else fall back to default.

So we have the following since that seems all that the agent needs

# config/initializers/content_security_policy.rb

...
policy.script_src  :self, 'bam.nr-data.net', 'js-agent.newrelic.com'
policy.connect_src :self, 'bam.nr-data.net'
...

However there isn’t any easier way to add csp nonce to ::NewRelic::Agent.browser_timing_header scripts. I wished there is a method for me to just pass in the nonce and have the agent insert those 2 script tags with the our nonce so we know those inline scripts are good.

This is my current hack and I was wondering if there is any better way to do this.

# config/newrelic.yml

development:
  browser_monitoring:
    auto_instrument: false

# app/views/layouts/application.html.erb

<!DOCTYPE html>
  <html dir="ltr">
    <head>
      <%= csrf_meta_tags %>
      <%= csp_meta_tag %>
      <%= javascript_tag nonce: true do -%>
        <%= :NewRelic::Agent.browser_timing_header.gsub!("<script>", "").gsub!("</script>", "") %>
      <% end -%>
     ...
   </head>
  ...

#2

Hey @Eric.Fung

Unfortunately this falls outside the scope of what we can officially support. When it comes to CSP, we can only tell you what the Browser agent requires. We can not instruct on how to configure CSP, or on how to edit the Browser script beyond what is provided by default.

That said I do hope that the wider community here can help if anyone has implemented similar.


#3

Oic o well … Thank you so much for you response anyway and I cleaned up the helper a bit as follow incase someone else is running into the same issue.

headers = ::NewRelic::Agent.browser_timing_header.scan(/<script>(.*?)<\/script>/).flatten
headers.map { |h| javascript_tag h, nonce: true }.join.html_safe

#4

Thanks for sharing that @Eric.Fung - I hope the community can either help here or benefit from the work you’ve already put into this :slight_smile:


#5

It’s odd that there isn’t a way to add nonce out of the box. Since the ruby agent is auto magically inserting those inline scripts. Pretty much anyone who turns on CSP without script-src: “unsafe-inline” will have an issue without doing some hacks like what I have above


#6

Thanks for your reply @Eric.Fung - This is something that has come up before - where a member of our product security team stepped in. Ian’s response in the thread below should give an indication to why our Browser script runs how it does:

As Ian mentions in that thread, nonce does negate the goals of CSP:

The issue with this approach is that in order to work correctly on browsers that do not support CSP Level 2’s inline script whitelisting functionality we would also need to include unsafe-inline in the CSP header we inject… this would have the effect of negating one of the major goals of using CSP - preventing inline scripts from running.

Hopefully this adds some clarity to our standpoint on this.