mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-30 17:13:08 +08:00
fix: protect appsrv default handlers (#22341)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
@@ -118,6 +118,7 @@ var (
|
||||
"enable_cloud_shell",
|
||||
"platform_names",
|
||||
"enable_change_owner_auto_rename",
|
||||
"default_handlers_whitelist_user_agents",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -463,12 +463,12 @@ func (app *Application) AddDefaultHandler(method string, prefix string, handler
|
||||
}
|
||||
|
||||
func (app *Application) addDefaultHandlers() {
|
||||
app.AddDefaultHandler("GET", "/version", VersionHandler, "version")
|
||||
app.AddDefaultHandler("GET", "/stats", StatisticHandler, "stats")
|
||||
app.AddDefaultHandler("POST", "/ping", PingHandler, "ping")
|
||||
app.AddDefaultHandler("GET", "/ping", PingHandler, "ping")
|
||||
app.AddDefaultHandler("GET", "/worker_stats", WorkerStatsHandler, "worker_stats")
|
||||
app.AddDefaultHandler("GET", "/process_stats", ProcessStatsHandler, "process_stats")
|
||||
app.AddDefaultHandler("GET", "/version", WhitelistFilter(VersionHandler), "version")
|
||||
app.AddDefaultHandler("GET", "/stats", WhitelistFilter(StatisticHandler), "stats")
|
||||
app.AddDefaultHandler("POST", "/ping", WhitelistFilter(PingHandler), "ping")
|
||||
app.AddDefaultHandler("GET", "/ping", WhitelistFilter(PingHandler), "ping")
|
||||
app.AddDefaultHandler("GET", "/worker_stats", WhitelistFilter(WorkerStatsHandler), "worker_stats")
|
||||
app.AddDefaultHandler("GET", "/process_stats", WhitelistFilter(ProcessStatsHandler), "process_stats")
|
||||
}
|
||||
|
||||
func timeoutHandle(h http.Handler) http.HandlerFunc {
|
||||
|
||||
@@ -60,12 +60,12 @@ func addPProfHandler(prefix string, app *Application) {
|
||||
} else {
|
||||
prefix = pp
|
||||
}
|
||||
app.AddHandler("GET", fmt.Sprintf("%s/", prefix), profIndex).SetProcessNoTimeout()
|
||||
app.AddHandler("GET", fmt.Sprintf("%s/cmdline", prefix), profCmdline).SetProcessNoTimeout()
|
||||
app.AddHandler("GET", fmt.Sprintf("%s/profile", prefix), profProfile).SetProcessNoTimeout()
|
||||
app.AddHandler("GET", fmt.Sprintf("%s/symbol", prefix), profSymbol).SetProcessNoTimeout()
|
||||
app.AddHandler("POST", fmt.Sprintf("%s/symbol", prefix), profSymbol).SetProcessNoTimeout()
|
||||
app.AddHandler("GET", fmt.Sprintf("%s/trace", prefix), profTrace).SetProcessNoTimeout()
|
||||
app.AddHandler("GET", fmt.Sprintf("%s/", prefix), WhitelistFilter(profIndex)).SetProcessNoTimeout()
|
||||
app.AddHandler("GET", fmt.Sprintf("%s/cmdline", prefix), WhitelistFilter(profCmdline)).SetProcessNoTimeout()
|
||||
app.AddHandler("GET", fmt.Sprintf("%s/profile", prefix), WhitelistFilter(profProfile)).SetProcessNoTimeout()
|
||||
app.AddHandler("GET", fmt.Sprintf("%s/symbol", prefix), WhitelistFilter(profSymbol)).SetProcessNoTimeout()
|
||||
app.AddHandler("POST", fmt.Sprintf("%s/symbol", prefix), WhitelistFilter(profSymbol)).SetProcessNoTimeout()
|
||||
app.AddHandler("GET", fmt.Sprintf("%s/trace", prefix), WhitelistFilter(profTrace)).SetProcessNoTimeout()
|
||||
}
|
||||
|
||||
func profIndex(_ context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package appsrv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/httputils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
)
|
||||
|
||||
var (
|
||||
whitelisUserAgents []string
|
||||
)
|
||||
|
||||
const kubeProbeUserAgent = "kube-probe"
|
||||
|
||||
func SetDefaultHandlersWhitelistUserAgents(userAgents []string) {
|
||||
for _, userAgent := range userAgents {
|
||||
whitelisUserAgents = append(whitelisUserAgents, strings.ToLower(userAgent))
|
||||
}
|
||||
if !utils.IsInArray(httputils.USER_AGENT, whitelisUserAgents) {
|
||||
whitelisUserAgents = append(whitelisUserAgents, httputils.USER_AGENT)
|
||||
}
|
||||
if !utils.IsInArray(kubeProbeUserAgent, whitelisUserAgents) {
|
||||
whitelisUserAgents = append(whitelisUserAgents, kubeProbeUserAgent)
|
||||
}
|
||||
}
|
||||
|
||||
func WhitelistFilter(handler FilterHandler) FilterHandler {
|
||||
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
for _, userAgent := range whitelisUserAgents {
|
||||
if strings.Contains(strings.ToLower(r.UserAgent()), userAgent) {
|
||||
handler(ctx, w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
log.Errorf("Forbidden default handler request: %s allow: %s", r.UserAgent(), strings.Join(whitelisUserAgents, ","))
|
||||
httperrors.ForbiddenError(ctx, w, "Forbidden")
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ func InitApp(options *common_options.BaseOptions, dbAccess bool) *appsrv.Applica
|
||||
// if dbConn != nil {
|
||||
// app.SetContext(appsrv.APP_CONTEXT_KEY_DB, dbConn)
|
||||
//}
|
||||
appsrv.SetDefaultHandlersWhitelistUserAgents(options.DefaultHandlersWhitelistUserAgents)
|
||||
if options.EnableAppProfiling {
|
||||
app.EnableProfiling()
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
)
|
||||
|
||||
@@ -77,6 +78,9 @@ func OnBaseOptionsChange(oOpts, nOpts interface{}) bool {
|
||||
if oldOpts.EnableChangeOwnerAutoRename != newOpts.EnableChangeOwnerAutoRename {
|
||||
consts.SetChangeOwnerAutoRename(newOpts.EnableChangeOwnerAutoRename)
|
||||
}
|
||||
if privatePrrefixesChanged(oldOpts.DefaultHandlersWhitelistUserAgents, newOpts.DefaultHandlersWhitelistUserAgents) {
|
||||
appsrv.SetDefaultHandlersWhitelistUserAgents(newOpts.DefaultHandlersWhitelistUserAgents)
|
||||
}
|
||||
return changed
|
||||
}
|
||||
|
||||
|
||||
@@ -129,6 +129,8 @@ type BaseOptions struct {
|
||||
|
||||
EnableChangeOwnerAutoRename bool `help:"Allows renaming when changing names" default:"false"`
|
||||
EnableDefaultPolicy bool `help:"Enable defualt policies" default:"true"`
|
||||
|
||||
DefaultHandlersWhitelistUserAgents []string `help:"whitelist user agents, default is empty"`
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
Reference in New Issue
Block a user