asp.net-web-apioauthoauth-2.0asp.net-coreaspnet-contrib

How to verify and change a JWT Alg


I'm using the ASP.Net OpenID Connect Server project (ASOS) to create and consume JWTs for my WebAPI.

I'm now trying to perform various validations on the token.

I'd like to know how to check the "alg" type. I'm aware of an issue where "none" can be passed in, which means that someone can forge the tokens (I'm not sure if it's just specific libraries that have the issue, or if it's just generally good practice to check, but I'd feel safer if I was performing that check).

Also, how can I verify the integrity of the JWT?

Currently my token issuer and WebAPI are in the same project so I'm guessing that it's checked for me automatically? Or is it not checked at all?

My understanding is that some kind of signing credential is added for you on disk if you don't specify any (Not sure where I read that).

Would providing some kind of signing credential automatically update the "alg" property?

What if my token issuer is on 1 server and my WebAPI was somewhere completely different. How would I go about validating that the token came from my token issuer and hadn't been interfered with.

Presumably I'd have to add a certificate manually, then share the public key somehow? If that's the case, could someone point me to where I should add the public key to check the JWT integrity? Presumably this part is more about asp.net Core than OpenIDConnect Server (ASOS)?

Thanks.


Solution

  • I'd like to know how to check the "alg" type.

    You can use a tool like jwt.io to read the header of a JWT, which contains the alg value you're looking for.

    I'm aware of an issue where "none" can be passed in, which means that someone can forge the tokens (I'm not sure if it's just specific libraries that have the issue, or if it's just generally good practice to check, but I'd feel safer if I was performing that check).

    ASOS relies on IdentityModel - a framework developed by Microsoft - to generate the JWT tokens (you can take a look at this other answer for more information). AFAIK, it was not impacted by the security bug you're mentioning.

    To try it yourself, you can use jwt.io to alter the alg header value and send the resulting encoded JWT to your API.

    Also, how can I verify the integrity of the JWT?

    Currently my token issuer and WebAPI are in the same project so I'm guessing that it's checked for me automatically? Or is it not checked at all?

    What if my token issuer is on 1 server and my WebAPI was somewhere completely different. How would I go about validating that the token came from my token issuer and hadn't been interfered with.

    Presumably I'd have to add a certificate manually, then share the public key somehow? If that's the case, could someone point me to where I should add the public key to check the JWT integrity? Presumably this part is more about asp.net Core than OpenIDConnect Server (ASOS)?

    If you use the JWT bearer middleware, then it's automatically done for you. For that, it directly downloads the public signing keys exposed by ASOS' JWK set endpoint (by default, at /.well-known/jwks).

    Here's an example:

    JWK Set

    My understanding is that some kind of signing credential is added for you on disk if you don't specify any (Not sure where I read that).

    This is true with the latest official version (beta6) but this feature will be removed in the next version. You'll be encouraged to register a X.509 certificate or use an ephemeral signing key (during development). An exception will be thrown if you don't.

    Would providing some kind of signing credential automatically update the "alg" property?

    Yes. ASOS natively supports both symmetric keys and RSA keys. For instance, if you use a SymmetricSecurityKey when calling options.SigningCredentials.AddKey(...), HS256 (HMAC-SHA256) will be returned instead of RS256 (RSA-SHA256). You can provide additional algorithms using the Add overload accepting a SigningCredentials instance.