I recently found a nice insecure direct object reference (IDOR) in New Relic which allowed me to pull data from other user accounts, and I thought it was worthy of writing up because it might make you think twice about the types (and the sheer number!) of API’s that are used in popular web services.
New Relic has a private bug bounty program (I was given permission to talk about it here), and I’ve been on their program for quite some time, so I’ve become very familiar with their overall setup and functionality of the application, but this bug took me a long time to find … and you’ll see why below.
Some background first: New Relic has a public REST API which can be used by anyone with a standard user account . This API operates by passing the X-api-key
header along with your query. Here’s an example of a typical API call:
curl -X GET 'https://api.newrelic.com/v2/applications/{application_id}/hosts.json' \ -H 'X-Api-Key:{api_key}' -i
Pretty typical. I tried to poke at this a little bit by swapping the {application_id}
with another user account’s {application_id}
that belongs to me. I usually test for IDOR’s this way, by having one browser (Usually Chrome) setup as my “victim account” and another browser (usually Firefox) as the “attacker” account, where I route everything through Burp and check the responses after I change values here and there. It’s kind of an old school way to test for IDOR’s and permission structure issues, and there is probably a much more effective way to automate something like this, but it works for me. Needless to say this was a dead end, and it didn’t return anything fruitful.
I looked further and found that New Relic also implements an internal API which occurs on both their infrastructure product and their alerts product. They conveniently identify this through the /internal_api/
endpoint (and put references to their internal API in some of their .js files as well).
The two products operate on different subdomains, infrastructure.newrelic.com
and alerts.newrelic.com
. This is what it looks like in Burp, on the alerts.newrelic.com
domain (where the IDOR originally occurred).
The reason I bring up the fact there are two separate subdomains is because this bug sat there for an excessive amount of time because I didn’t bother checking both subdomains and their respective internal API’s. To make it even more difficult, there are multiple versions of the internal_api, and the bug only worked on version 1. Here’s what the vulnerable endpoint looked like:
https://alerts.newrelic.com/internal_api/1/accounts/{ACCOUNT NUMBER}/incidents
The account number increases by 1 every time a new account is created, so I could have literally enumerated every single account pretty easily by just running an intruder attack and increasing the value by one each time. The IDOR was possible because the application did not ensure that the account number being requested through the above internal API GET request matched the account number of the authenticated user.
This IDOR allowed me to view the following from any New Relic account:
- Account Events
- Account Messages
- Violations (Through NR Alerts)
- Policy Summaries
- Infrastructure events and filters
- Account Settings
This bug has been resolved and I was rewarded $1,000. I’d just like to point out that the New Relic engineering and development team was super quick to remediate this. Special thanks to the New Relic team for running one of, if not the best bug bounty programs out there!
Follow me on Twitter to stay up to date with what I’m working on and security/bug bounties in general 🙂