Davigor
Davigor

Reputation: 403

Best practices for securely granting user credential access to other internal services (API key)?

I have a Ruby on Rails application with a database that stores sensitive user information (hashed with Devise). I now need to pass some of this sensitive information to another internal service on another server that needs it to make calls to third party APIs, so it needs a way to request that information from the RoR app.

What's the best approach to something like this? My first intuition was to grant an internal API key that would grant access to all sensitive information in the DB (via a private endpoint), the same way developer keys give access to a subset of API endpoints. Is this secure enough as long as I hash the API key? What's the best approach to passing sensitive information around through internal services?

Upvotes: 0

Views: 199

Answers (1)

Exadra37
Exadra37

Reputation: 13104

Private APIs

My first intuition was to grant an internal API key that would grant access to all sensitive information in the DB (via a private endpoint), the same way developer keys give access to a subset of API endpoints

Well private endpoints or private APIs don't exist in the sense of only protecting them by using an API key. From a web app you only need to see the html source code to be able to find the API keys. In mobile devices you can see how easy is to reverse engineer API keys in this series of articles about Mobile API Security Techniques. While the articles are in the context of mobile devices, some of the techniques used are also valid in other type of APIs. I hope you can see now how someone could grab the API key and abuse from the API you are trying to secure.

Now even if you don't expose the API key in a mobile app or web app, the API is still discoverable, specially if the endpoint is served by the same API used for the other public endpoints. This is made even easier when you tell in robots.txt that bots should not access some of the endpoints, because this is the first place where hackers look into for trying to enumerate attack vectors into your APIs.

Possible Solutions

Private API Solution

What's the best approach to something like this? My first intuition was to grant an internal API key that would grant access to all sensitive information in the DB (via a private endpoint)

In order to have a private API the server hosting it needs to be protected by a firewall and locked to the other internal server consuming it with certificate pinning and maybe also by IP address. In order to be able to properly secure and lock down the internal server hosting the supposed private API it MUST not support any public requests.

Certificate Pinning:

Pinning effectively removes the "conference of trust". An application which pins a certificate or public key no longer needs to depend on others - such as DNS or CAs - when making security decisions relating to a peer's identity. For those familiar with SSH, you should realize that public key pinning is nearly identical to SSH's StrictHostKeyChecking option. SSH had it right the entire time, and the rest of the world is beginning to realize the virtues of directly identifying a host or service by its public key.

Database Direct Access Solution

What's the best approach to passing sensitive information around through internal services?

Personally I would prefer to access the database directly from the other server and have the database software itself configured to only accept requests from specific internal servers for specific users with the less privileges possible to perform the action they need. Additionally you would employ the firewall locking to and use certificate pinning between the internal servers.

Conclusion

No matter what solution you choose place your database with the sensitive data in server that only hosts that database and is very well lock-down to your internal network.

Anyone needing to access that sensitive data MUST have only read privileges for that specific database table.

Upvotes: 2

Related Questions