mirror of
https://github.com/juanfont/headscale.git
synced 2026-04-11 03:27:20 +02:00
types: fix OIDC identifier path traversal dropping subject
url.JoinPath resolves path-traversal segments like '..' and '.', which silently drops the OIDC subject from the identifier. For example, Iss='https://example.com' with Sub='..' produces 'https://example.com' — the subject is lost entirely. This causes distinct OIDC users to receive colliding identifiers. Replace url.JoinPath with simple string concatenation using a slash separator. This preserves the subject literally regardless of its content. url.PathEscape does not help because dots are valid URL path characters and are not escaped.
This commit is contained in:
committed by
Kristoffer Dalby
parent
4064f13bda
commit
3529fe0da1
@@ -304,21 +304,14 @@ func (c *OIDCClaims) Identifier() string {
|
||||
subject := c.Sub
|
||||
|
||||
var result string
|
||||
// Try to parse as URL to handle URL joining correctly
|
||||
if u, err := url.Parse(issuer); err == nil && u.Scheme != "" { //nolint:noinlineerr
|
||||
// For URLs, use proper URL path joining
|
||||
if joined, err := url.JoinPath(issuer, subject); err == nil { //nolint:noinlineerr
|
||||
result = joined
|
||||
}
|
||||
}
|
||||
|
||||
// If URL joining failed or issuer wasn't a URL, do simple string join
|
||||
if result == "" {
|
||||
// Default case: simple string joining with slash
|
||||
issuer = strings.TrimSuffix(issuer, "/")
|
||||
subject = strings.TrimPrefix(subject, "/")
|
||||
result = issuer + "/" + subject
|
||||
}
|
||||
// Always use simple string concatenation with a slash separator.
|
||||
// url.JoinPath resolves path-traversal segments like ".." and ".",
|
||||
// which can silently drop the subject and cause identifier collisions
|
||||
// between distinct OIDC users (e.g., Sub=".." produces the same
|
||||
// identifier as an empty Sub).
|
||||
issuer = strings.TrimSuffix(issuer, "/")
|
||||
subject = strings.TrimPrefix(subject, "/")
|
||||
result = issuer + "/" + subject
|
||||
|
||||
// Clean the result and return it
|
||||
return CleanIdentifier(result)
|
||||
|
||||
Reference in New Issue
Block a user