Drop jsonwebtoken dependency#94
Conversation
|
👋 Thanks for assigning @tnull as a reviewer! |
|
Fixes #92 |
7ff7d0a to
bdd21e1
Compare
Note you'll have to put that in the OP otherwise it doesn't link the issue. |
| base64 = { version = "0.22.1", optional = true, default-features = false, features = ["std"] } | ||
| bitcoin_hashes = { version = "0.19", optional = true, default-features = false } | ||
| hex-conservative = { version = "1.0", optional = true, default-features = false } | ||
| rsa = { version = "0.9.10", optional = true, default-features = false, features = ["sha2"] } |
There was a problem hiding this comment.
We already have openssl in our tree - I do wonder if we could use openssl::rsa (https://docs.rs/openssl/latest/openssl/rsa/index.html) rather than this additional dependency?
There was a problem hiding this comment.
Thank you yes great idea
tnull
left a comment
There was a problem hiding this comment.
Thanks for the update, some minor comments, otherwise looks good.
However, I think vss-server in general gets into the realm where it could use some some fuzzing or proptest coverage to ensure that our implementations behave as expected, are safe, never panic, etc.
|
|
||
| const BEARER_PREFIX: &str = "Bearer "; | ||
|
|
||
| fn parse_public_key_pem(pem: &str) -> Result<PKey<Public>, String> { |
There was a problem hiding this comment.
Should we just return () or, if you prefer, a proper enum error type here? Using a string introduces some unnecessary allocations, and they can't easily be handled. Same goes for new then ofc.
| serde_json = { version = "1.0.149", optional = true, default-features = false, features = ["std"] } | ||
|
|
||
| [dev-dependencies] | ||
| jsonwebtoken = { version = "9.3.0", default-features = false, features = ["use_pem"] } |
There was a problem hiding this comment.
If we already keep it as a dev dependency, can we add some parity/backwards compat tests that ensure our new custom implementation behaves the same way as this did?
|
@tankyleo Gentle ping here. |
|
Let me know what you think tnull, that last commit expands the scope of this PR a little where I add optional validation of |
|
🔔 1st Reminder Hey @tnull! This PR has been waiting for your review. |
tnull
left a comment
There was a problem hiding this comment.
Generally LGTM, but added some comments that Codex had for me. Seems they might be worth addressing even if not major?
Let me know what you think tnull, that last commit expands the scope of this PR a little where I add optional validation of exp claims, thought we could get this done along the way
Sounds good, though, AFAIU Codex thinks the validation didn't use to be optional before?
| return Err(VssError::AuthError(String::from("The token is expired"))); | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Codex:
- High - rust/auth-impls/src/jwt.rs:103-118: aud is ignored. The old validator rejected tokens with an audience when no expected audience was configured; this now accepts tokens minted for another audience/service if signed by the same issuer.
| .map_err(|_| VssError::AuthError(String::from("Claims json decode failed")))?; | ||
|
|
||
| // Check if the token is expired | ||
| if let Some(exp) = claims.exp { |
There was a problem hiding this comment.
Codex:
- High - rust/auth-impls/src/jwt.rs:39-40, rust/auth-impls/src/jwt.rs:111-116: JWTs without exp are now accepted. main used jsonwebtoken::Validation::new(Algorithm::RS256), which requires exp by default, so this creates non-expiring bearer tokens unless that policy change is
intentional.
|
|
||
| const BEARER_PREFIX: &str = "Bearer "; | ||
|
|
||
| fn parse_public_key_pem(pem: &str) -> Result<PKey<Public>, ()> { |
There was a problem hiding this comment.
Codex:
- Medium - rust/auth-impls/src/jwt.rs:45-54, rust/auth-impls/src/jwt.rs:94-98: RS256 is not tied to an RSA key. PKey::public_key_from_der accepts generic public keys, and OpenSSL verifies using the configured key type, so non-RSA keys are not rejected at setup. █
- Medium - rust/auth-impls/src/jwt.rs:45-54: PEM parsing regressed to exact -----BEGIN PUBLIC KEY----- SPKI input. jsonwebtoken::from_rsa_pem also accepted common PKCS#1 -----BEGIN RSA PUBLIC KEY----- inputs, so some existing configs may fail to start.
|
Thanks addressed review, also passed the code through codex :) |
Yes Codex is right, I misunderstood things given our old |
| /// Refer: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2 | ||
| sub: String, | ||
| /// Expiration Time | ||
| exp: u64, |
There was a problem hiding this comment.
Codex:
- rust/auth-impls/src/jwt.rs:40: exp is now deserialized as u64 in the application claims. The old production path decoded into Claims { sub } and let jsonwebtoken validate exp separately, which accepted JWT NumericDate values encoded as JSON floats. Tokens with valid fractional exp values
will now fail with Claims json decode failed, so this is a compatibility regression.
Maybe that's fine?
There was a problem hiding this comment.
Yes I gave it some thought, would prefer to only add this if there is user demand.
This removes `time` from the dependency tree because the crate shipped a security fix behind an MSRV bump. Fixes lightningdevkit#92. We make a best effort attempt to keep the same behavior as when we validated JWTs using `jsonwebtoken`. This includes rejecting any JWTs that have the `aud` field set. We also keep `jsonwebtoken` as a dev-dependency and add parity tests. Unlike `jsonwebtoken`, we now fail to decode JWTs that contain `exp` fields with fractional parts.
4422d39 to
9ec254d
Compare
|
Squashed with no further changes |
Fixes #92.