@@ -735,36 +735,38 @@ func (k *JWTMiddleware) processCentralisedJWT(r *http.Request, token *jwt.Token)
735735 // We need a base policy as a template, either get it from the token itself OR a proxy client ID within Tyk
736736 basePolicyID , foundPolicy = k .getBasePolicyID (r , claims )
737737 if ! foundPolicy {
738- if len (k .Spec .JWTDefaultPolicies ) == 0 {
739- k .reportLoginFailure (baseFieldData , r )
740- return errors .New ("key not authorized: no matching policy found" ), http .StatusForbidden
741- } else {
738+ // Only use default policies if configured - scope mapping may provide policies later
739+ if len (k .Spec .JWTDefaultPolicies ) > 0 {
742740 isDefaultPol = true
743741 basePolicyID = k .Spec .JWTDefaultPolicies [0 ]
744742 }
745743 }
746744
747- session , err = k .Gw .generateSessionFromPolicy (basePolicyID ,
748- k .Spec .OrgID ,
749- true )
745+ // Only generate from policy if we have a base policy ID
746+ if basePolicyID != "" {
747+ session , err = k .Gw .generateSessionFromPolicy (basePolicyID ,
748+ k .Spec .OrgID ,
749+ true )
750750
751- // If base policy is one of the defaults, apply other ones as well
752- if isDefaultPol {
753- for _ , pol := range k . Spec . JWTDefaultPolicies {
754- if ! contains (session .ApplyPolicies , pol ) {
755- session . ApplyPolicies = append ( session . ApplyPolicies , pol )
751+ if isDefaultPol {
752+ for _ , pol := range k . Spec . JWTDefaultPolicies {
753+ if ! contains ( session . ApplyPolicies , pol ) {
754+ session . ApplyPolicies = append (session .ApplyPolicies , pol )
755+ }
756756 }
757757 }
758- }
759758
760- if err := k .ApplyPolicies (& session ); err != nil {
761- return errors .New ("failed to create key: " + err .Error ()), http .StatusInternalServerError
762- }
759+ if err := k .ApplyPolicies (& session ); err != nil {
760+ return errors .New ("failed to create key: " + err .Error ()), http .StatusInternalServerError
761+ }
763762
764- if err != nil {
765- k .reportLoginFailure (baseFieldData , r )
766- k .Logger ().Error ("Could not find a valid policy to apply to this token!" )
767- return errors .New ("key not authorized: no matching policy" ), http .StatusForbidden
763+ if err != nil {
764+ k .reportLoginFailure (baseFieldData , r )
765+ k .Logger ().Error ("Could not find a valid policy to apply to this token!" )
766+ return errors .New ("key not authorized: no matching policy" ), http .StatusForbidden
767+ }
768+ } else {
769+ session = user.SessionState {OrgID : k .Spec .OrgID }
768770 }
769771
770772 //override session expiry with JWT if longer lived
@@ -784,22 +786,23 @@ func (k *JWTMiddleware) processCentralisedJWT(r *http.Request, token *jwt.Token)
784786 // extract policy ID from JWT token
785787 basePolicyID , foundPolicy = k .getBasePolicyID (r , claims )
786788 if ! foundPolicy {
787- if len (k .Spec .JWTDefaultPolicies ) == 0 {
788- k .reportLoginFailure (baseFieldData , r )
789- return errors .New ("key not authorized: no matching policy found" ), http .StatusForbidden
790- } else {
789+ if len (k .Spec .JWTDefaultPolicies ) > 0 {
791790 isDefaultPol = true
792791 basePolicyID = k .Spec .JWTDefaultPolicies [0 ]
793792 }
794793 }
795- // check if we received a valid policy ID in claim
796- k .Gw .policiesMu .RLock ()
797- policy , ok := k .Gw .policiesByID [basePolicyID ]
798- k .Gw .policiesMu .RUnlock ()
799- if ! ok {
800- k .reportLoginFailure (baseFieldData , r )
801- k .Logger ().Error ("Policy ID found is invalid!" )
802- return errors .New ("key not authorized: no matching policy" ), http .StatusForbidden
794+ // check if we received a valid policy ID in claim (skip if no base policy for scope-only auth)
795+ var policy user.Policy
796+ var ok bool
797+ if basePolicyID != "" {
798+ k .Gw .policiesMu .RLock ()
799+ policy , ok = k .Gw .policiesByID [basePolicyID ]
800+ k .Gw .policiesMu .RUnlock ()
801+ if ! ok {
802+ k .reportLoginFailure (baseFieldData , r )
803+ k .Logger ().Error ("Policy ID found is invalid!" )
804+ return errors .New ("key not authorized: no matching policy" ), http .StatusForbidden
805+ }
803806 }
804807 // check if token for this session was switched to another valid policy
805808 pols := session .PolicyIDs ()
@@ -827,7 +830,7 @@ func (k *JWTMiddleware) processCentralisedJWT(r *http.Request, token *jwt.Token)
827830 }
828831 }
829832
830- if ! contains (pols , basePolicyID ) || defaultPolicyListChanged {
833+ if basePolicyID != "" && ( ! contains (pols , basePolicyID ) || defaultPolicyListChanged ) {
831834 if policy .OrgID != k .Spec .OrgID {
832835 k .reportLoginFailure (baseFieldData , r )
833836 k .Logger ().Error ("Policy ID found is invalid (wrong ownership)!" )
@@ -872,11 +875,13 @@ func (k *JWTMiddleware) processCentralisedJWT(r *http.Request, token *jwt.Token)
872875 }
873876
874877 if scope := getScopeFromClaim (claims , scopeClaimName ); len (scope ) > 0 {
875- polIDs := []string {
876- basePolicyID , // add base policy as a first one
878+ // Start with base policy if it exists
879+ polIDs := []string {}
880+ if basePolicyID != "" {
881+ polIDs = []string {basePolicyID }
877882 }
878883
879- // // If specified, scopes should not use default policy
884+ // If specified, scopes should not use default policy
880885 if isDefaultPol {
881886 polIDs = []string {}
882887 }
@@ -910,6 +915,24 @@ func (k *JWTMiddleware) processCentralisedJWT(r *http.Request, token *jwt.Token)
910915 return errors .New ("key not authorized: could not apply several policies" ), http .StatusForbidden
911916 }
912917
918+ } else if basePolicyID == "" && exists {
919+ // Security: existing session with no scope in token and no base policy
920+ // Reject to prevent privilege escalation (token should reset policies)
921+ k .reportLoginFailure (baseFieldData , r )
922+ k .Logger ().Error ("Existing session requires scope or base policy when scope mapping is configured" )
923+ return errors .New ("key not authorized: no scope or policy in token" ), http .StatusForbidden
924+ }
925+ }
926+
927+ if basePolicyID == "" && len (k .Spec .JWTDefaultPolicies ) == 0 {
928+ if len (session .PolicyIDs ()) == 0 {
929+ k .reportLoginFailure (baseFieldData , r )
930+ k .Logger ().Error ("No policies could be determined from token (no base policy, no valid scopes)" )
931+ return errors .New ("key not authorized: no matching policy found" ), http .StatusForbidden
932+ } else if exists && len (k .Spec .GetScopeToPolicyMapping ()) == 0 {
933+ k .reportLoginFailure (baseFieldData , r )
934+ k .Logger ().Error ("Existing session requires policy in token when no defaults configured" )
935+ return errors .New ("key not authorized: no matching policy found" ), http .StatusForbidden
913936 }
914937 }
915938
0 commit comments