Get as image function pulls any Insights/NRQL data from any New Relic account (IDOR)

This writeup walks you through the full process as to how I found a pretty bad Insecure Direct Object Reference (IDOR) in New Relic. 

In New Relic, there is the ability to add a 3rd party integration to a product line called New Relic Infrastructure. Common integrations include AWS, Azure, and most recently Google Cloud Platform (GCP). In Google Cloud Platform there is also the ability to create dashboards:

new relic dashboards

Dashboards are pretty common in New Relic, but there was something unique about the dashboards that are within the integrations section; the dropdown options for each chart allow you to do the following actions, which are not present in any of the other dashboard areas:

The option that immediately stood out to me was the “Get as image” option. This option converts the NRQL query that generates the dashboard into an image – and this is where the vulnerability lies. For more info on the New Relic Query Language (NRQL) works, check out this link:

https://docs.newrelic.com/docs/insights/nrql-new-relic-query-language/nrql-resources/nrql-syntax-components-functions

The normal POST request to generate the dashboard image is as follows:

{"query":{"account_id":1523936,"nrql":"SELECT count(*) FROM IntegrationError FACET dataSourceName SINCE 1 DAY AGO"},"account_id":1523936,"endpoint":"/v2/nrql","title":"Authentication Errors"}

The application failed to check and see if the account_id parameter belonged to the user making the request. The account number 1523936 belongs to me, but if I changed it to another number, I could pull data from another account.

So now that I had control over this value, I could change the account ID to any other account ID on New Relic. Since the account ID parameter is incremental, if I was malicious I could simply throw this request into Burp Intruder and highlight the account id value to increment by one on each request, enabling me to pull any data I wanted from any or all accounts on New Relic. The NRQL query could be modified as well, so instead of pulling the data that generated the original dashboard, I could instead change the request to something like this:

{"query":{"account_id":any_account_number_here,"nrql":"SELECT * FROM SystemSample"},"account_id":any_account_number_here,"endpoint":"/v2/nrql","title":"Uh oh!"}

This query runs the SystemSample NRQL query on any account ID, which downloads the following photo:

So this is interesting, but it doesn’t really tell me any juicy info. I know that I’m hitting other accounts, but the information I’m retrieving back is useless – it just shows an empty chart! I played around with this for a little while, trying different NRQL queries until I discovered an interesting header that is in the response back from the server when you send this type of request:

X-Image-Url: http://gorgon.nr-assets.net/image/{UNIQUE_ID}

I realized that if you add ?type= at the end of the URL it will show you different chart types, allowing you to exfiltrate more data than normal. If you enter a incorrect “?type=” value, it will show you all of the available chart options within the error message:

{"code":"BadRequestError","message":"uhoh is not a valid Vizco chart type. Permitted Types: apdex area bar baseline billboard bullet empty event-feed funnel heatmap histogram json line markdown pie stacked-horizontal-bar scatter table traffic-light vertical-bar"}

Now I can use any of the above chart types of return more information than I normally would from the NRQL query:

X-Image-Url: http://gorgon.nr-assets.net/image/{UNIQUE_ID}?type=json

Now we’re getting somewhere! Instead of the normal chart type, I’m now returning a JSON dump of the dashboard, downloaded as a photo. This is pretty great considering I can perform this JSON dump against any account – but I want to go one step further. How can I exfiltrate as much data as possible in each request? Just add a &height=2000 at the end of the URL 🙂

X-Image-Url: http://gorgon.nr-assets.net/image/{UNIQUE_ID}?type=json&height=2000

I reported this to the New Relic team and they fixed it shortly afterwards within a few days. I was awarded $2,500 for this bug. I asked them if they wanted to include any comment on this post about how they fixed the issue, and they provided the following:

For some background, this report helped us identify a logic error with the validation code we have in place in our backend authentication proxy. A very specific combination of configuration options for an application would result in the validation checks not taking place.

Once we identified that issue, we were able to search for anywhere we were using that combination of configuration options to quickly mitigate the issue. That then led to a permanent fix of the logic issue, ensuring that the account validation always took place before the request was allowed to proceed.

The New Relic security team is one of the best ones out there – they award quickly and their time to resolution is fantastic. It’s really one of the main reasons I enjoy hunting for bugs on them so much!

Follow me on Twitter to stay up to date with what I’m working on and security/bug bounties in general 🙂

3 responses

  1. Great write up! thanks for share!

  2. Thanks for your write up!!! Continue we all love that!!!

  3. Dylan Dylan Avatar
    Dylan Dylan

    Great write up.