3

I'm very new to Spring. I'm trying to create a REST API using Spring Boot and I'm stuck whether to expose my user's primary key or not which also happens to be their email. Something like api/user/example@gmail.com. A big part of me says it's okay since it would sensible to expose it as it is the identifier for that specific record when viewing, deleting, and updating. Is there a security risk for this? What is the best practice for such implementation? Right now I'm combining the @PathVariable and @RequestBody. I didn't like the idea of putting my primary key in the RequestBody thinking that it might pose a risk...or is there?

@RequestMapping(value = "/updateUser/{customerEmail}", method = RequestMethod.POST)
    public ApiResult updateCustomer(@RequestBody UserDetailsDto userDetailsDto, @PathVariable String customerEmail) {
    //service call...
}
codex
  • 432
  • 2
  • 7
  • 18
  • I would be an unhappy user if I saw my email was exposed. Doubly unhappy if my email was also used as party of authentication. – Andrew S Jul 20 '20 at 19:58
  • @AndrewS yeah but how would you perform an update or delete if the identifier (email) is not put in the URL? I cannot encrypt the email too since it'd be cumbersome to perform search in the database level. Do you have an alternative? I see Facebook is using the user's username for their profile URLs. – codex Jul 20 '20 at 20:03
  • 1
    have another id for your user - one that you supply ( a number or something) when someone registers they use their mail but you supply the id in the server and thats what they will later see when someone gets a profile show that number in the url. (an elaborate example will be that in facebook they use a customizable name as link to your profile) – Gabriel H Jul 20 '20 at 20:09
  • @GabrielH Ohh, I can't believe I missed that. I was hoping to reduce the number of keys to reduce complexity that is why I used the email as the primary key. So I'll just have to assign a new primary key something called "username" and have the email as another attribute but have it unique as well. – codex Jul 20 '20 at 20:21

4 Answers4

1

Spring is a good framework of choice, usually as long as the identifier is unique it should be fine, the problem with using an email is you are exposing your users data more easily which could be problematic to the users, I would suggest you rather use a string of unique characters as an identifier in the form of:

  • http://api.example.com/user-management/users/{id} as an example http://api.example.com/user-management/users/22

in this case identifier of user 22 has the email example@gmail.com in this way you are not exposing sensitive data when doing an update here is a link that gives guidance on best naming practice https://restfulapi.net/resource-naming/.

Another tip given in the link provided is to avoid using URI's as CRUD (Create, Read, Update, Delete) functionality "URIs should be used to uniquely identify resources and not any action upon them".

mpho mahase
  • 136
  • 5
1

First of all, user e-mail is often considered to be PII (Personally Identifiable Information). As such it would be unwise to put it into a URL, because you should not put any sensitive information into the URL. Header - ok, body - too. But not into the URL. The reason is, that all the proxies/load balancers/other infrastructure you have or might have in the future will always be allowed to log URLs for debug reasons. And you don't want your sensitive data to leak across the components like this. No company policy would ever allow that.

Marek Puchalski
  • 3,286
  • 2
  • 26
  • 35
  • Alright, so it's fair to say that it's fine to put it in the body? Also would it be a good idea to make the email just a regular attribute and create a new pkey say, "username" to put it in the URL as a replacement for the email? – codex Jul 21 '20 at 09:54
  • Also, assuming the "email" wasn't a PII, would it still be fine to expose the primary key in the URL to be used for viewing, updating, and deleting? If not, is there a best practice for this? – codex Jul 21 '20 at 09:57
  • Depends on the context (there could also be an issue with "insecure direct object references" if you don't authenticate and check access control properly), but I'd say if email was not PII then putting in into URL is ok. – Marek Puchalski Jul 21 '20 at 10:09
  • Body is ok. Username - if not PII - is ok too. Again. As long as you don't create insecure direct object references. – Marek Puchalski Jul 21 '20 at 10:12
  • 1
    I see your point on the IDOR. Alright thanks for sharing. – codex Jul 21 '20 at 10:22
0

Any sensitive information (in this case email but in other case that could also be your database autoincremented primary key field ID in your table) should not be exposed.

Once way to go around that that I know and I use is to have 2 fields. For example, I have table USER {ID, USERID, NAME, ...}

Above, ID is autoincremented Long field representing PK.

USERID on the other hand, is a field generated of random characters or GUID which I use to pass back and fort in REST calls.

So, I might have record in USER table as:

USER {1, "a23asf60asdaare998700asdfasr70po097", "Mike", ...}

If I were to pass ID=1 back and forth, a malicious user could easily deduce what it is and how to query next user. For that reason, i pass USERID which represent a public and safe version of ID that can be passed and no one can know what would be the USERID of next user.

So, your response model, dto model etc should have these fields and response model should return USERID instead of returning ID. And you can use JPA to find the user by the USERID (so, based on that, that method must be called in this case findByUserId).

The same would apply for your case where you use email instead of ID if you want dont want to expose user emails which make sense to me.

Hope that helps.

pixel
  • 9,653
  • 16
  • 82
  • 149
-1

I think it's more a matter of taste and personal beliefs rather than objective aspects.

Since HTTPS is more or less mandatory today, it's a lot harder to obtain the e-mail address by just sniffing with a tool like Wireshark.

So what's the possible risk? Since users have to be authorized to call this endpoint, they know at least their own e-mail address and most likely used it to authenticate. So a user can't modify or acquire the data of another user, if properly implemented.

A problem which may be of concern is that it might be possible to check for a registered e-mail during the registration process. Depending on what kind of application you're developing, this might be an issue. To give a brief example of such a case: Imagine a catholic priest registered on a porn site or the e-mail address of your husband/wife registered on a dating platform.

So may advice: Force HTTPS and you are pretty fine to use them as a primary key. However, if you have the possibility to abstract this, I'd do so. A numerical key or username may be a better choice and also easier to handle - but it makes no difference. Imagine if you have an endpoint to acquire the user's data, including e-mail address. It just doesn't matter if you acquire this data by a numerical key or by the e-mail address. In the end, you end up with the e-mail address in the response's body. And if this body is accessible by someone, he can also access the username and password, thus rendering any security measurement you've taken useless.

maio290
  • 6,440
  • 1
  • 21
  • 38