2

Personal Identifiable Information (PII) should be considered sensitive information and OWASP states that sensitive data should not be part of the URL. https://owasp-aasvs.readthedocs.io/en/latest/requirement-9.1.html

GDPR states that "an online identifier" identifying a person directly or indirectly is PII. https://gdpr.eu/article-4-definitions/

An API providing user preferences where a resource item could look like:

{
  "id": "abc123"           //generated id
  "language": "en_EN",
  "favoriteColor": "BLUE",
  "userId": "peter@example.com"
}

Would it then be ok for an API to have a link to this resource?

https://example.com/user-preferences/abc123 

From my understanding this would be an example of an indirect online identifier. Does that mean the id needs to be encrypted? And if that is the case - does that mean each encryption of the id (i.e every time a URL is provided from the API) must encrypted with a different salt to avoid introducing a new indirect identifier?

Different URLs for the same resource:

https://example.com/user-preferences/87wytu09ufwc2ercler4ri // abc123 encrypted with salt A
https://example.com/user-preferences/diu4w98iuywfgommbvwdxe // abc123 encrypted with salt B

1 Answers1

2

What we have here is security and compliance requirements having direct impact on our API design. Indeed, it is considered bad practice to put sensitive data into the URLs (reason - every proxy, load balancer, API gateway, web server, ... along the way is allowed to log URLs of incoming requests for debug purposes and we do not want sensitive data to be spread this way). On the other way - doing GET requests ends up being tricky, because we can not put all the stuff we would like to simply into the request body. Parameters of GET requests end up in URL because HTTP and REST is designed this way.

So, what can we do then, to satisfy security and compliance needs? At least two things come to my mind.

  1. Put sensitive data into request headers. They will not end up being part of URL so problem solved.
  2. Solve the problem just how you have proposed to. It is nothing new to the industry. Just follow the path of solving insecure direct object references.

I would go for 1 myself. It is less mysterious than 2 in case of what is going on and how to handle test data.

Marek Puchalski
  • 3,286
  • 2
  • 26
  • 35
  • 1
    Thanks. I guess it all depends on how the API is expected to be used by consumers? If there is a need to enable passing resources with links to other clients I would need to do as in alt. 2 and that comes with a trickier implementation. Alt 1 would be easier to implement and a valid alternative if the API will be used by consumers that are actually building or generating client code for my API, then it is possible to add the header to the API request. – Niklas Eldberger Feb 08 '22 at 12:17
  • Sounds good to me. – Marek Puchalski Feb 08 '22 at 13:38
  • the problem with the solution 1 is that header has a limit, you can read more here: https://stackoverflow.com/questions/686217/maximum-on-http-header-values And as you said the request pass through a lot of components as api gateway, load balancers and so on, and every component put new headers in the request. So you need to be very careful on puting custom data in headers – gabriel felipe kalb Jun 13 '22 at 12:20