deprecate authJWTInHTTPQuery and disable JWTs in query parameters (#5648)
This fixes a long standing security flaw. Even though it's a breaking change, few users should be impacted since this feature has been discouraged for some time.
This commit is contained in:
+4
-2
@@ -270,6 +270,10 @@ components:
|
||||
type: string
|
||||
authJWTClaimKey:
|
||||
type: string
|
||||
authJWTInHTTPQuery:
|
||||
type: boolean
|
||||
nullable: true
|
||||
deprecated: true
|
||||
authJWTIssuer:
|
||||
type: string
|
||||
authJWTAudience:
|
||||
@@ -278,8 +282,6 @@ components:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/AuthInternalUserPermission'
|
||||
authJWTInHTTPQuery:
|
||||
type: boolean
|
||||
|
||||
# Control API
|
||||
api:
|
||||
|
||||
@@ -63,7 +63,7 @@ func matchesPermission(perms []conf.AuthInternalUserPermission, req *Request) bo
|
||||
return false
|
||||
}
|
||||
|
||||
func getToken(jwtInHTTPQuery bool, req *Request) (string, bool) {
|
||||
func getToken(jwtInHTTPQuery *bool, req *Request) (string, bool) {
|
||||
switch {
|
||||
case req.Credentials.Token != "":
|
||||
return req.Credentials.Token, true
|
||||
@@ -72,7 +72,8 @@ func getToken(jwtInHTTPQuery bool, req *Request) (string, bool) {
|
||||
return req.Credentials.Pass, true
|
||||
|
||||
// always allow passing tokens through query parameters with RTSP and RTMP since there's no alternative.
|
||||
case req.Protocol == ProtocolRTSP || req.Protocol == ProtocolRTMP || (jwtInHTTPQuery && isHTTP(req)):
|
||||
case req.Protocol == ProtocolRTSP || req.Protocol == ProtocolRTMP ||
|
||||
(jwtInHTTPQuery != nil && *jwtInHTTPQuery && isHTTP(req)):
|
||||
v, err := url.ParseQuery(req.Query)
|
||||
if err == nil {
|
||||
if len(v["token"]) == 1 {
|
||||
@@ -100,7 +101,7 @@ type Manager struct {
|
||||
JWTJWKSFingerprint string
|
||||
JWTClaimKey string
|
||||
JWTExclude []conf.AuthInternalUserPermission
|
||||
JWTInHTTPQuery bool
|
||||
JWTInHTTPQuery *bool
|
||||
JWTIssuer string
|
||||
JWTAudience string
|
||||
ReadTimeout time.Duration
|
||||
|
||||
@@ -268,7 +268,7 @@ type Conf struct {
|
||||
AuthJWTJWKSFingerprint string `json:"authJWTJWKSFingerprint"`
|
||||
AuthJWTClaimKey string `json:"authJWTClaimKey"`
|
||||
AuthJWTExclude []AuthInternalUserPermission `json:"authJWTExclude"`
|
||||
AuthJWTInHTTPQuery bool `json:"authJWTInHTTPQuery"`
|
||||
AuthJWTInHTTPQuery *bool `json:"authJWTInHTTPQuery,omitempty" deprecated:"true"`
|
||||
AuthJWTIssuer string `json:"authJWTIssuer"`
|
||||
AuthJWTAudience string `json:"authJWTAudience"`
|
||||
|
||||
@@ -437,7 +437,6 @@ func (conf *Conf) setDefaults() {
|
||||
},
|
||||
}
|
||||
conf.AuthJWTClaimKey = "mediamtx_permissions"
|
||||
conf.AuthJWTInHTTPQuery = true
|
||||
|
||||
// Control API
|
||||
conf.APIAddress = ":9997"
|
||||
@@ -727,6 +726,10 @@ func (conf *Conf) Validate(l logger.Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
if conf.AuthJWTInHTTPQuery != nil {
|
||||
l.Log(logger.Warn, "parameter 'authJWTInHTTPQuery' is deprecated and will be removed in a future release")
|
||||
}
|
||||
|
||||
// Control API (deprecated params)
|
||||
|
||||
if conf.APIAllowOrigin != nil {
|
||||
|
||||
@@ -739,7 +739,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
|
||||
newConf.AuthJWTJWKSFingerprint != p.conf.AuthJWTJWKSFingerprint ||
|
||||
newConf.AuthJWTClaimKey != p.conf.AuthJWTClaimKey ||
|
||||
!reflect.DeepEqual(newConf.AuthJWTExclude, p.conf.AuthJWTExclude) ||
|
||||
newConf.AuthJWTInHTTPQuery != p.conf.AuthJWTInHTTPQuery ||
|
||||
!reflect.DeepEqual(newConf.AuthJWTInHTTPQuery, p.conf.AuthJWTInHTTPQuery) ||
|
||||
newConf.AuthJWTIssuer != p.conf.AuthJWTIssuer ||
|
||||
newConf.AuthJWTAudience != p.conf.AuthJWTAudience ||
|
||||
newConf.ReadTimeout != p.conf.ReadTimeout
|
||||
|
||||
@@ -149,10 +149,6 @@ authJWTClaimKey: mediamtx_permissions
|
||||
# Actions to exclude from JWT-based authentication.
|
||||
# Format is the same as the one of user permissions.
|
||||
authJWTExclude: []
|
||||
# Allow passing the JWT through query parameters of HTTP requests (i.e. ?token=JWT).
|
||||
# This is a security risk and will be disabled in the future.
|
||||
# RTSP and RTMP always allow JWT in query even if disabled, since there is no alternative.
|
||||
authJWTInHTTPQuery: true
|
||||
# Expected issuer (iss) claim in the JWT. Leave empty to skip validation.
|
||||
authJWTIssuer:
|
||||
# Expected audience (aud) claim in the JWT. Leave empty to skip validation.
|
||||
|
||||
Reference in New Issue
Block a user