Skip to content

Commit

Permalink
Force authorization requests to have a public user nkey.
Browse files Browse the repository at this point in the history
This will be required for the user claim sent back from the authorization service to avoid replay attacks.

Signed-off-by: Derek Collison <derek@nats.io>
  • Loading branch information
derekcollison committed Dec 14, 2022
1 parent a07c95d commit 1ddecee
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
6 changes: 6 additions & 0 deletions v2/authorization_claims.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ type ClientTLS struct {
// will be sent to an external authorization service.
type AuthorizationRequest struct {
Server ServerID `json:"server_id"`
UserNkey string `json:"user_nkey"`
ClientInformation ClientInformation `json:"client_info"`
ConnectOptions ConnectOptions `json:"connect_opts"`
TLS *ClientTLS `json:"client_tls,omitempty"`
Expand All @@ -98,6 +99,11 @@ func NewAuthorizationRequestClaims(subject string) *AuthorizationRequestClaims {

// Validate checks the generic and specific parts of the auth request jwt.
func (ac *AuthorizationRequestClaims) Validate(vr *ValidationResults) {
if ac.UserNkey == "" {
vr.AddError("User nkey is required")
} else if !nkeys.IsValidPublicUserKey(ac.UserNkey) {
vr.AddError("User nkey %q is not a valid user public key", ac.UserNkey)
}
ac.ClaimsData.Validate(vr)
}

Expand Down
22 changes: 22 additions & 0 deletions v2/authorization_claims_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,30 @@ func TestNewAuthorizationClaims(t *testing.T) {
ac.Server.Name = "NATS-1"

vr := CreateValidationResults()

// Make sure that user nkey is required.
ac.Validate(vr)
if vr.IsEmpty() || !vr.IsBlocking(false) {
t.Fatalf("Expected blocking error on an nkey user not being specified")
}

// Make sure it is required to be valid public user nkey.
ac.UserNkey = "derek"
vr = CreateValidationResults()
ac.Validate(vr)
if vr.IsEmpty() || !vr.IsBlocking(false) {
t.Fatalf("Expected blocking error on invalid user nkey")
}

kp, err := nkeys.CreateUser()
if err != nil {
t.Fatalf("Error creating user: %v", err)
}
pub, _ := kp.PublicKey()

ac.UserNkey = pub
vr = CreateValidationResults()
ac.Validate(vr)
if !vr.IsEmpty() {
t.Fatal("Valid authorization request will have no validation results")
}
Expand Down

0 comments on commit 1ddecee

Please sign in to comment.