olivine-labs / lua-jwt Goto Github PK
View Code? Open in Web Editor NEWJSON Web Token library
License: MIT License
JSON Web Token library
License: MIT License
Currently, we only support JWS
@DorianGray I can not file an issue at your lua-cjson repo because it is a fork.
I appreciate the addition to that module because the empty table encoding of cjson can be frustrating. Unfortunately, you've published this module to luarocks declaring 'cjson' as the modules one and only name(space). This is a big problem for my other projects. For example, I've recently submitted a patch to openresty to increase maximum float precision for cjson. I use this for generating sequence ID's between server and client. Unfortunately, that project is now broken because I used luarocks to install lua-jwt which pulls in lua-cjson-ol as a dependency.
I'm not sure what the best way to fix this in luarocks is. Maybe @leafo can help. Would it be possible to publish an updated version of this module that uses a different namespace entirely?
Please look into: https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
This library is vulnerable bcoz it is not taking algorithm as an option while decoding.
According to the rfc7515 the result of hash function(signature) should not be converted to hash string, but only BASE64URL encoded:
Computing the HMAC of the JWS Signing Input ASCII(BASE64URL(UTF8(JWS
Protected Header)) || '.' || BASE64URL(JWS Payload)) with the HMAC
SHA-256 algorithm using the key specified in Appendix A.1 and
base64url-encoding the result yields this BASE64URL(JWS Signature)
value:dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
Currently the library is not interoperable with other JWT libraries(see results with debugger at https://jwt.io). The tests should be probably changed to compare raw values instead of working with the values computed by the library's encode function:
https://github.com/Olivine-Labs/lua-jwt/blob/master/spec/jwt_spec.lua#L40
Hello,
Thank you very much for contributing this library. All of your modules are high quality.
This module is potentially vulnerable to an algorithm/key mismatch attack. In summary, if a token producer and consumer have a mutual understanding that they will sign/verify tokens using RSA and not HMAC, it is possible in some cases to generate forged tokens to bypass token verification. I've been reading around and it seems like people are getting around this by including the fingerprint of the RSA key in the header table when signing. The verifier then validates this fingerprint against the calculated fingerprint that it already has.
Here is a busted test for jwt_spec.lua that demonstrates the problem.
it("is not vulnerable to algorithm/key mismatch attack", function()
local keyPair = crypto.pkey.generate("rsa", 512)
-- The known trusted key between priver and audience
-- Distributed to audience that expects RSA signed tokens
--
-- Perhaps I'm running a service and use a separate auth
-- provider. They've given me this public key for token
-- validation. Or the public key is known publicly.
--
-- Pre-requisite for this issue
known_trusted_public_key = keyPair:to_pem()
-- Generate a legitimate token for our audience
function service_sign_token(claims)
local keys = {
private = keyPair
}
return jwt.encode(claims, { alg = "RS256", keys = keys })
end
-- Verify rsa tokens from our provider. Because....
-- I use a provider that only generates rsa tokens?
--
-- In the real world, this is likely not written in the
-- same language as our signer, let alone the same lib.
--
-- This makes this test a bit contrived but only trying
-- to demonstrate the flaw. In this case, this lib is
-- only safe from this attack if the user is feeding
-- a crypto.pkey public key object to the decoder.
--
-- And thats only because crypto.hmac.digest can not
-- handle userdata arguments for key.
function validate_token_from_service(token)
return jwt.decode(token, { keys = { public = known_trusted_public_key }})
end
-- Claim to something private that only the admin should have access to
local claims = {
claim_to_access_customer_data = true
}
local legit_token = service_sign_token(claims)
assert.truthy(legit_token ~= nil)
local legit_claim, err = validate_token_from_service(legit_token)
assert.same(claims, legit_claim) -- all good
-- Now someone has gotten a hold of the public key. Maybe it's sitting somewhere public for web traffic.
-- Generate a forged packet and bi-pass the provider entirely
local forged_token = jwt.encode(claims, {alg = "HS256", keys = { private = known_trusted_public_key }})
forged_claim, err = validate_token_from_service(forged_token)
assert.are_not.same(claims, forged_claim)
end)
What's the license for this library?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.