Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(refactor): python-jose is removed from project.optional-dependency. #3549

Closed

Conversation

Squidtyper
Copy link

in security, the tokens' encode and decode now uses pyjwt.

Description

Closes

@Squidtyper Squidtyper requested review from a team as code owners June 6, 2024 12:24
@github-actions github-actions bot added area/dependencies This PR involves changes to the dependencies size: small pr/external Triage Required 🏥 This requires triage labels Jun 6, 2024
@Squidtyper Squidtyper changed the title python-jose is removed from project.optional-dependency. refractor: python-jose is removed from project.optional-dependency. Jun 6, 2024
@provinzkraut
Copy link
Member

Thanks @Squidtyper, this is a welcome change!
Am I correct to assume this is motivated by the maintenance status of python-jose?

@Squidtyper
Copy link
Author

Yes. We are eliminating the use of python-jose in our own code and we think litestar is better off with pyjwt as well. It's my first time contributing. I see there are some errors.

@Alc-Alc Alc-Alc changed the title refractor: python-jose is removed from project.optional-dependency. chore(refactor): python-jose is removed from project.optional-dependency. Jun 6, 2024
pyproject.toml Outdated Show resolved Hide resolved
@cofin
Copy link
Member

cofin commented Jun 6, 2024

before merging this, I would like to evaluate this library instead of pyjwt. Both python-jose and pyjwt have gone through periods of inactivity in their history.

@cofin cofin added the do not merge Don't merge this label Jun 6, 2024
@sherbang
Copy link
Contributor

before merging this, I would like to evaluate this library instead of pyjwt. Both python-jose and pyjwt have gone through periods of inactivity in their history.

joserfc and the authlib project as a whole are certainly interesting, but it seems to me that pyjwt is the better option right now.

We can start with Snyk Advisor scores of 79 for joserfc vs 91 for pyjwt which also shows more consistent commit activity for the last 2 years for pyjwt.

Pyjwt is simply a much more popular package right now, which suggests it's more likely to have some longevity, it has far more contributors, and thus far more eyes on it for future security issues.

The authlib project is interesting, in that they've built a small company around the auth code they've built, but looking at the activity graph of their github suggests that they haven't been very active in this for a while, so it may be a dying effort.

However, either of these packages would be an improvement over python-jose, which has unresolved security issues. I suggest that the priority now should be removing python-jose, and not delaying over considering which replacement library is marginally better.

Ref: jpadilla/pyjwt#942

@provinzkraut
Copy link
Member

joserfc and the authlib project as a whole are certainly interesting, but it seems to me that pyjwt is the better option right now.

I agree. pyjwt is the de-facto standard and does everything we need here. It being the most popular JWT library also has the benefit that if users are doing something else with JWTs outside what Litestar provides, it's most likely this is the library they'll be using.

@cofin
Copy link
Member

cofin commented Jun 21, 2024

However, either of these packages would be an improvement over python-jose, which has unresolved security issues. I suggest that the priority now should be removing python-jose, and not delaying over considering which replacement library is marginally better.

Agree with this.

So that we don't get bogged down without a fix, I'm inclined to go with this change. It can be revisited should there be a need.

@cofin cofin removed do not merge Don't merge this Triage Required 🏥 This requires triage labels Jun 21, 2024
@cofin cofin force-pushed the replace-python-jose-by-pyjwt branch from 4e1a021 to e76d3fe Compare August 8, 2024 13:33
@github-actions github-actions bot added area/private-api This PR involves changes to the privatized API size: medium and removed size: small labels Aug 8, 2024
@cofin cofin requested a review from provinzkraut as a code owner August 8, 2024 21:55
@github-actions github-actions bot added the area/docs This PR involves changes to the documentation label Aug 8, 2024
@JacobCoffee
Copy link
Member

im having trouble getting docs build to work

@provinzkraut provinzkraut force-pushed the replace-python-jose-by-pyjwt branch 2 times, most recently from 1be42d5 to 2084b75 Compare August 15, 2024 16:37
@github-actions github-actions bot added size: small and removed area/docs This PR involves changes to the documentation area/private-api This PR involves changes to the privatized API size: medium labels Aug 15, 2024
Copy link
Member

@provinzkraut provinzkraut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Squidtyper Sorry for the long turnaround time on this. After the discussion we had about this, I agree with @cofin that this is okay to go in.

I've left two comments to address, once that's done, this can be merged.

Comment on lines +94 to +96
def base64url_decode(code: str) -> bytes:
padding = "=" * (4 - (len(code) % 4))
return base64.urlsafe_b64decode(code + padding)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we doing custom b64 decoding here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +98 to +116
if isinstance(secret, str):
converted_secret: AllowedPublicKeys | str | bytes = secret
else:
if secret["kty"] == "RSA":
n = int.from_bytes(base64url_decode(secret["n"]), byteorder="big")
e = int.from_bytes(base64url_decode(secret["e"]), byteorder="big")
converted_secret = rsa.RSAPublicNumbers(e, n).public_key(default_backend())
elif secret["kty"] == "EC":
x = int.from_bytes(base64url_decode(secret["x"]), byteorder="big")
y = int.from_bytes(base64url_decode(secret["y"]), byteorder="big")
converted_secret = ec.EllipticCurvePublicNumbers(x, y, ec.SECP256R1()).public_key(default_backend())
elif secret["kty"] == "OKP" and secret["crv"] == "Ed25519":
x = base64url_decode(secret["x"])
converted_secret = ed25519.Ed25519PublicKey.from_public_bytes(x)
elif secret["kty"] == "OKP" and secret["crv"] == "Ed448":
x = base64url_decode(secret["x"])
converted_secret = ed448.Ed448PublicKey.from_public_bytes(x)
else:
raise TypeError("The secret is not a form of allowed public key.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes seem to be unrelated to the switch to pyjwt. If this is a feature you want to add, this should be done in a separate PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@provinzkraut Some details from the author would be good, but I do believe this is park of the JWK/backend implementations here: https://github.com/mpdavis/python-jose/tree/master/jose

@provinzkraut
Copy link
Member

im having trouble getting docs build to work

@JacobCoffee There were some accidental commits in here. I've cleaned the branch and now everything's good. There seems to be however an issue with the pdm.lock / pyproject.toml.

@provinzkraut
Copy link
Member

Closing this in favour of #3684, so we can get a release out.

@Squidtyper If you want to complete the work on the features you've started here, feel free to open another PR for this! :)

@Squidtyper
Copy link
Author

Thank you a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/dependencies This PR involves changes to the dependencies pr/external pr/internal size: small
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants