MM-55320 - Limit length of browser user agent version; ratelimit the /sessions endpoint (#25900)
* add ratelimit to /sessions; cap userAgent version length; tests * add MaxSessionsLimit; remove oldest session first; tests * can't use slices in 1.20; improve test * nits * add GetLRUSessions; move limiting to CreateSession; remove rate limiting * use queryBuilder * mysql needs a limit when using offset * update i18n * refactor into limitNumberOfSessions; protect createSessionForUserAccessToken * add comment to GetLRUSessions * add limit to oauth path; PR comments
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
9a2d96073e
Коммит
17d11db395
@@ -10,6 +10,8 @@ import (
|
||||
"github.com/avct/uasurfer"
|
||||
)
|
||||
|
||||
const maxUserAgentVersionLength = 128
|
||||
|
||||
var platformNames = map[uasurfer.Platform]string{
|
||||
uasurfer.PlatformUnknown: "Windows",
|
||||
uasurfer.PlatformWindows: "Windows",
|
||||
@@ -86,27 +88,33 @@ func getOSName(ua *uasurfer.UserAgent) string {
|
||||
func getBrowserVersion(ua *uasurfer.UserAgent, userAgentString string) string {
|
||||
if index := strings.Index(userAgentString, "Mattermost Mobile/"); index != -1 {
|
||||
afterVersion := userAgentString[index+len("Mattermost Mobile/"):]
|
||||
return strings.Fields(afterVersion)[0]
|
||||
// MM-55320: limitStringLength prevents potential DOS caused by filling an unbounded string with junk data
|
||||
return limitStringLength(strings.Fields(afterVersion)[0], maxUserAgentVersionLength)
|
||||
}
|
||||
|
||||
if index := strings.Index(userAgentString, "Mattermost/"); index != -1 {
|
||||
afterVersion := userAgentString[index+len("Mattermost/"):]
|
||||
return strings.Fields(afterVersion)[0]
|
||||
return limitStringLength(strings.Fields(afterVersion)[0], maxUserAgentVersionLength)
|
||||
}
|
||||
|
||||
if index := strings.Index(userAgentString, "mmctl/"); index != -1 {
|
||||
afterVersion := userAgentString[index+len("mmctl/"):]
|
||||
return strings.Fields(afterVersion)[0]
|
||||
return limitStringLength(strings.Fields(afterVersion)[0], maxUserAgentVersionLength)
|
||||
}
|
||||
|
||||
if index := strings.Index(userAgentString, "Franz/"); index != -1 {
|
||||
afterVersion := userAgentString[index+len("Franz/"):]
|
||||
return strings.Fields(afterVersion)[0]
|
||||
return limitStringLength(strings.Fields(afterVersion)[0], maxUserAgentVersionLength)
|
||||
}
|
||||
|
||||
return getUAVersion(ua.Browser.Version)
|
||||
}
|
||||
|
||||
func limitStringLength(field string, limit int) string {
|
||||
endPos := min(len(field), limit)
|
||||
return field[:endPos]
|
||||
}
|
||||
|
||||
func getUAVersion(version uasurfer.Version) string {
|
||||
if version.Patch == 0 {
|
||||
return fmt.Sprintf("%v.%v", version.Major, version.Minor)
|
||||
@@ -151,3 +159,11 @@ func getBrowserName(ua *uasurfer.UserAgent, userAgentString string) string {
|
||||
|
||||
return browserNames[uasurfer.BrowserUnknown]
|
||||
}
|
||||
|
||||
// min should be replaced by to go 1.21 built-in generic function, see MM-57356.
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user