Skip to content

Go: Add JWT Algorithm Confusion and JWT decoding without Signature Verification #14081

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

Closed
wants to merge 11 commits into from

Conversation

Kwstubbs
Copy link
Contributor

@Kwstubbs Kwstubbs commented Aug 29, 2023

This PR adds support for detecting JWT go algorithm confusion vulnerability and decoding without signature verification. After opening this pull request, I noticed that my PR shares some similarity to this PR. This PR models some of lestrrat-go and the default go library

@github-actions
Copy link
Contributor

QHelp previews:

go/ql/src/experimental/CWE-347/JWTParsing.qhelp

errors/warnings:

A fatal error occurred: Failed to read path ./go/ql/src/experimental/CWE-347/JWTParsing.ql
(eventual cause: NoSuchFileException "./go/ql/src/experimental/CWE-347/JWTParsing.ql")

@am0o0
Copy link
Contributor

am0o0 commented Aug 29, 2023

@Kwstubbs why there is a lot of files that changed in my and your query is like this?
also for more clarification in one of the queries I used two taint tracking module to fully support finding keyFunc of some golang jwt libraries that accepting func type as their arguments.
Also should I open all for one query as you wrote a similar query ?
Ahh OK, the vendor directory make my pull request so big :))

@Kwstubbs
Copy link
Contributor Author

@amammad We will have to reduce the size of our vendor folders with https://github.com/github/depstubber, just having a little trouble on my end getting it to work so I opened the PR first. The all for one if up to you, our PRs seems to have some overlap, but are not exactly the same. If you have find a CVE that is a signature verification issue and is modeled by your PR, feel free to open a bounty.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 5, 2023

QHelp previews:

go/ql/src/experimental/CWE-347/JWTParsingAlgorithm.qhelp

JWT Method Check

Not verifying the JWT algorithim present in a JWT token when verifying its signature may result in algorithim confusion.

Recommendation

Before presenting a key to verify a signature, ensure that the key corresponds to the algorithim present in the JWT token.

Example

The following code uses the asymmetric public key to verify the JWT token and assumes that the algorithim is RSA. By not checking the signature, an attacker can specify the HMAC option and use the same public key, which is assumed to be public and often at endpoint /jwt/jwks.jso, to sign the JWT token and bypass authentication.

package main

import (
	"fmt"

	"github.com/golang-jwt/jwt/v5"
)

type JWT struct {
	privateKey []byte
	publicKey  []byte
}

func (j JWT) Validate(token string) (interface{}, error) {
	key, err := jwt.ParseRSAPublicKeyFromPEM(j.publicKey)
	if err != nil {
		return "", fmt.Errorf("validate: parse key: %w", err)
	}

	tok, err := jwt.Parse(token, func(jwtToken *jwt.Token) (interface{}, error) {

		return key, nil
	})
	if err != nil {
		return nil, fmt.Errorf("validate: %w", err)
	}

	claims, ok := tok.Claims.(jwt.MapClaims)
	if !ok || !tok.Valid {
		return nil, fmt.Errorf("validate: invalid")
	}

	return claims["dat"], nil
}

References

@smowton
Copy link
Contributor

smowton commented Sep 11, 2023

@Kwstubbs could you address the code scanning findings flagged above and the test failures?

Copy link
Contributor

@owen-mc owen-mc left a comment

Choose a reason for hiding this comment

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

We need a qhelp file for JWTParsingSignature as well.

Comment on lines +64 to +69
/**
* A v2 Function to parse token that check token signature.
*/
class LestrratParse extends Function {
LestrratParse() { this.hasQualifiedName(packageLestrrat(), "Parse") }
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This model isn't used anywhere. Did you mean to use it somewhere? Or did you model it for completeness? Consider deleting - the model can easily be added in future if it is needed.

@owen-mc
Copy link
Contributor

owen-mc commented Sep 22, 2023

The requirement for a review from @codeql-ci-reviewers is spurious. It's because you've vendored the dependencies and one of them contains a .bzl file. You should stub the dependencies using depstubber.

@owen-mc
Copy link
Contributor

owen-mc commented Oct 17, 2023

@Kwstubbs Do you think you'll get to this at some point?

@Kwstubbs
Copy link
Contributor Author

@owen-mc I was waiting for @amammad 's Go JWT pull request to merge since there is some overlap and his was opened first and part of a bounty so I didnt want to cause conflicts. I will work on this today.

@Kwstubbs
Copy link
Contributor Author

Kwstubbs commented Oct 18, 2023

@owen-mc It seems that @amammad 's changes create a lot of conflicts. I will close this PR and open two new ones (in couple days), one focusing on the algorithm confusion and the other focusing on the additional lestrrat sinks for the "no signature verification" methods, that way things are simpler and easier to merge/understand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants