did-app / did-elixir

DID is an Identity Provider, that authenticates users by verifying access to either an email address or securely stored private key.
https://did.app
Apache License 2.0
47 stars 2 forks source link

Token Claims #7

Open Exadra37 opened 4 years ago

Exadra37 commented 4 years ago

I am giving a try to DID and I like the concept as a whole, but I have some remarks that I would like to mention.

Token Claims

On a success login we get this Token Claims:

%{
  "aud" => "test_xxxxxx",
  "email" => "yyyyy@gmail.com",
  "email_verified" => true,
  "exp" => 1586642486,
  "iat" => 1586642366,
  "iss" => "https://did.app",
  "nonce" => nil,
  "sub" => "cc694f41-56b0-4a6d-9f7e-bc60cd660290"
}

Why are you leaking the following?

Client ID in DID.app

In my opinion this could not be revealed, but do you have a reason to have it in the claims?

User Email

This is the type of data that can be retrieved by using the sub claim to query the DID backend. I understand that may be convenient, but at least I would like that this value would not be there by default. Maybe an option to not include it in the DID Dashboard?

The email is verified

You can achieve the same by signing the token with an invalid CLIENT_SECRET, thus when the backend is not able to verify the token signature it knows the token is invalid. This means that the email is not indeed verified or that the token was tampered with.

But if you want to keep the current flow of letting the backend know that the email is indeed not verified, then you can sign the token with the CLIENT_INVALID_SECRET.

With this approach you don't reveal to an attacker introspecting the claims If the token represents a valid user or not.

JWE Instead of JWS

Currently signed tokens(JWS) are being used, that leave the claims publicly exposed, and an alternative would be to use encrypted tokens(JWE), did you though about using JWE?

CrowdHailer commented 4 years ago

Client ID in DID.app

Just to confirm, do you mean the aud claim? To check the token is for your service you should validate that the aud is the client_id for your service.

As much as possible I am trying to follow the OpenID spec https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation point 3

User Email,

What would be the value of not including it to a site implementing DID?

The email is verified

I don't quite understand your suggestion here, sorry. Tokens aren't signed with the CLIENT_SECRET but a publically available key at the jwks url

JWE Instead of JWS

The OpenID standard does include the option for supporting encryption, it's something we would add. For now we are trying to validate the user flow for end users and developers integrating DID at the moment so it's not a top priority. If someone explained that they required it for an application then I guess yes we would jump it up the priority list.

Exadra37 commented 4 years ago

Client ID in DID.app

Just to confirm, do you mean the aud claim?

Yes

To check the token is for your service you should validate that the aud is the client_id for your service.

So at least you could hash it, then I would do the same in my backend, and I would know that it's the client_id I expect, thus not revealing it to the world.

User Email,

What would be the value of not including it to a site implementing DID?

Client privacy, data protection, preventing client emails collection just by collecting them from networks attacks or even more usual from logs. Developers forgot how often Logs can be the source of a Data Breach. Logs contain too much valuable data, that lots of us don't even realize.

Remember GDPR fines are huge, therefore anything we can do to reduce exposure of Personal Identifiable Information(PII) we must do, otherwise GDPR in a data breach will take it as you have not done enough to protect the user data.

It's a common mistaken across the developer community to include more data then it should in normal JWS tokens. You just need to include a uuid that it seems you already do in the sub claim, and then the backend of the client should be the one responsible to query the DID backend to retrieve the PII data it needs, like the user email.

The email is verified

I don't quite understand your suggestion here, sorry.

No problem. I also made the assumption you where using secrets, when it's using a public key to verify them.

Tokens aren't signed with the CLIENT_SECRET but a publicly available key at the jwks url

Oh I see, that defeats the solution that I was proposing, because they are public available, while if the JWS was signed with a secret, it would be only known by the DID backend and the client backend, therefore allowing for JWS tokens to not reveal to the outside world if they represent a valid authentication or an invalid one.

JWE Instead of JWS

If someone explained that they required it for an application then I guess yes we would jump it up the priority list.

As I mention PII information needs to be kept private all the time, and in my opinion JWE should be the only option available when PII data is included in a token, despite what any standard may say, because standards are always lagging years behind the needs of the real world. Bear in mind that I am not saying that standards are not good or should not be followed, by the contrary, but sometimes you have to upgrade them on your own when it makes sense, like in PII data protection.

asianfilm commented 4 years ago

On the subject of emails being in the token claim, I think there are different use cases.

I'd like the user to have the option of logging in anonymously or not. If not, then my website can examine the email address and decide whether they have specific privileges. If anonymous, then they may have limited access to my website, perhaps only with the ability to save data/preferences in local storage.

The above assumes that the email address is reliable, which for me means that it has been verified (by DID) in the past, say, 7 days. Like mobile phone numbers, email addresses can be recycled. Or when someone leaves a company they can be terminated, and I don't want that person to have access.

-- On other issues above, since the aud claim is being sent securely to my backend, which already has the client id in an environment variable, I like that I can compare them. Perhaps with a SPA, I would have some concern that the user would have access to it, or perhaps that's solved with PKCE.

As an alternative to JWT, JWS and JWE, I've been looking at PASETO, which was "developed as a simpler, more secure alternative to JWTs".