api-design

Restful API: Sensitive data in url


I'd like to create an API to get customer details.

The URL can be - GET /customers/{customerId}.

My question is customerId being sensitive data, is it okay to pass it in the URL?

If not, what would be the best way to do that?


Solution

  • The first question, is customerId really sensitive? At some point your client will pass the identifier for resources through to the API. Even if you encrypt the value, or package it within the payload as a POST request, the value can still be inspected and can still be faked by a client or packet sniffer who really wants to access or change it.

    A: Yes, you can pass the customerId in the url

    This is a standard expectation in fact it can be counter intuitive to try to work around passing the Id in the route, it will be far easier to code for and manage a REST based API if the Id is part of the route.

    But it is possible...

    The specific implementation will depend on your runtime and code framework, but as a design pattern It is possible to write a re-write module or middle-ware into the server such that an encrypted query string is decrypted and then the response pipeline redirected internally to the internal or secure route. By doing it this way, you are injecting this security layer in between the standard API processing and do not have to code in any special hacks at each endpoint to resolve the Id that was passed from the client.

    However...

    This means that the client side will have to encrypt or compute the value to send to the API, which means that now the client has the code that can create the tokens so it is a trivial task to reverse engineer the logic and create your own tokens to other customers.

    Instead of encryption

    In the last project I came across like this, it was a vanity issue. We didn't want the user to try and hack the system by changing the Ids in the URL and in some cases they just didn't want the user to feel like a number...

    So in this case, its less about real security or confidentiality and 100% what I call Vanity.

    In this way, the client calls an endpoint on the API with the parameters and it returns a token. I did use encryption in the end to avoid storing the original parameters, but the point is the API returns a token that it knows how to decypher.

    You might be familiar with Tiny URL services, this is pretty much the same concept.

    I found it simpler to user encryption, in this case the server holds both the encrypt and decrypt keys so I am not concerned that someone with an infected client could compromise security, but again, this wasn't implemented as a security feature.