Remote code execution on the host system via MongoDB shell in jumpserver
Description
JumpServer is an open source bastion host. An authenticated user can exploit a vulnerability in MongoDB sessions to execute arbitrary commands, leading to remote code execution. This vulnerability may further be leveraged to gain root privileges on the system. Through the WEB CLI interface provided by the koko component, a user logs into the authorized mongoDB database and exploits the MongoDB session to execute arbitrary commands. This vulnerability has been addressed in versions 2.28.20 and 3.7.1. Users are advised to upgrade. There are no known workarounds for this vulnerability.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/jumpserver/kokoGo | >= 2.0.0, < 2.28.20 | 2.28.20 |
github.com/jumpserver/kokoGo | >= 3.0.0, < 3.7.1 | 3.7.1 |
Affected products
1- Range: >= 2.0.0, < 2.28.20
Patches
26 files changed · +58 −4
entrypoint.sh+8 −0 modified@@ -6,6 +6,14 @@ do echo "wait for jms_core $CORE_HOST ready" sleep 2 done +# 限制所有可执行目录的权限 +chmod -R 700 /usr/local/sbin/* && chmod -R 700 /usr/local/bin/* +chmod -R 700 /usr/sbin/* && chmod -R 700 /sbin/* && chmod -R 700 /bin/* + + +# 放开部分需要的可执行权限 +chmod 755 `which mysql` `which psql` `which mongosh` `which tsql` `which redis` `which clickhouse-client` +chmod 755 `which kubectl` `which rawkubectl` `which helm` `which rawhelm` cd /opt/koko ./koko
pkg/srvconn/conn_mongodb.go+7 −1 modified@@ -8,6 +8,7 @@ import ( "strconv" "time" + "github.com/jumpserver/koko/pkg/logger" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -92,7 +93,12 @@ func (conn *MongoDBConn) Close() error { func startMongoDBCommand(opt *sqlOption) (lcmd *localcommand.LocalCommand, err error) { cmd := opt.MongoDBCommandArgs() - lcmd, err = localcommand.New("mongosh", cmd, localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + opts, err := BuildNobodyWithOpts(localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + if err != nil { + logger.Errorf("build nobody with opts error: %s", err) + return nil, err + } + lcmd, err = localcommand.New("mongosh", cmd, opts...) if err != nil { return nil, err }
pkg/srvconn/conn_nobody.go+23 −0 added@@ -0,0 +1,23 @@ +package srvconn + +import ( + "os/user" + "strconv" + "syscall" + + "github.com/jumpserver/koko/pkg/localcommand" +) + +func BuildNobodyWithOpts(opts ...localcommand.Option) (nobodyOpts []localcommand.Option, err error) { + nobody, err := user.Lookup("nobody") + if err != nil { + return nil, err + } + uid, _ := strconv.Atoi(nobody.Uid) + gid, _ := strconv.Atoi(nobody.Gid) + nobodyOpts = make([]localcommand.Option, 0, len(opts)+1) + nobodyOpts = append(nobodyOpts, opts...) + nobodyCredential := localcommand.WithCmdCredential(&syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}) + nobodyOpts = append(nobodyOpts, nobodyCredential) + return nobodyOpts, nil +}
pkg/srvconn/conn_postgresql.go+7 −1 modified@@ -5,6 +5,7 @@ import ( "os" "strconv" + "github.com/jumpserver/koko/pkg/logger" _ "github.com/lib/pq" "github.com/jumpserver/koko/pkg/localcommand" @@ -61,7 +62,12 @@ func (conn *PostgreSQLConn) Close() error { func startPostgreSQLCommand(opt *sqlOption) (lcmd *localcommand.LocalCommand, err error) { argv := opt.PostgreSQLCommandArgs() //psql 是启动postgresql的客户端 - lcmd, err = localcommand.New("psql", argv, localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + opts, err := BuildNobodyWithOpts(localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + if err != nil { + logger.Errorf("build nobody with opts error: %s", err) + return nil, err + } + lcmd, err = localcommand.New("psql", argv, opts...) if err != nil { return nil, err }
pkg/srvconn/conn_redis.go+7 −1 modified@@ -9,6 +9,7 @@ import ( "time" "github.com/jumpserver/koko/pkg/localcommand" + "github.com/jumpserver/koko/pkg/logger" "github.com/mediocregopher/radix/v3" ) @@ -95,7 +96,12 @@ func (conn *RedisConn) Close() error { func startRedisCommand(opt *sqlOption) (lcmd *localcommand.LocalCommand, err error) { cmd := opt.RedisCommandArgs() - lcmd, err = localcommand.New("redis-cli", cmd, localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + opts, err := BuildNobodyWithOpts(localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + if err != nil { + logger.Errorf("build nobody with opts error: %s", err) + return nil, err + } + lcmd, err = localcommand.New("redis-cli", cmd, opts...) if err != nil { return nil, err }
pkg/srvconn/conn_sqlserver.go+6 −1 modified@@ -72,7 +72,12 @@ func startSQLServerCommand(opt *sqlOption) (lcmd *localcommand.LocalCommand, err func startSQLServerNormalCommand(opt *sqlOption) (lcmd *localcommand.LocalCommand, err error) { //tsql 是启动sqlserver的客户端 - return localcommand.New("tsql", opt.SQLServerCommandArgs()) + opts, err := BuildNobodyWithOpts(localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + if err != nil { + logger.Errorf("build nobody with opts error: %s", err) + return nil, err + } + return localcommand.New("tsql", opt.SQLServerCommandArgs(), opts...) } func tryManualLoginSQLServerServer(opt *sqlOption, lcmd *localcommand.LocalCommand) (*localcommand.LocalCommand, error) {
6 files changed · +58 −4
entrypoint.sh+8 −0 modified@@ -6,6 +6,14 @@ do echo "wait for jms_core $CORE_HOST ready" sleep 2 done +# 限制所有可执行目录的权限 +chmod -R 700 /usr/local/sbin/* && chmod -R 700 /usr/local/bin/* +chmod -R 700 /usr/sbin/* && chmod -R 700 /sbin/* && chmod -R 700 /bin/* + + +# 放开部分需要的可执行权限 +chmod 755 `which mysql` `which psql` `which mongosh` `which tsql` `which redis` `which clickhouse-client` +chmod 755 `which kubectl` `which rawkubectl` `which helm` `which rawhelm` cd /opt/koko ./koko
pkg/srvconn/conn_mongodb.go+7 −1 modified@@ -8,6 +8,7 @@ import ( "strconv" "time" + "github.com/jumpserver/koko/pkg/logger" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -92,7 +93,12 @@ func (conn *MongoDBConn) Close() error { func startMongoDBCommand(opt *sqlOption) (lcmd *localcommand.LocalCommand, err error) { cmd := opt.MongoDBCommandArgs() - lcmd, err = localcommand.New("mongosh", cmd, localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + opts, err := BuildNobodyWithOpts(localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + if err != nil { + logger.Errorf("build nobody with opts error: %s", err) + return nil, err + } + lcmd, err = localcommand.New("mongosh", cmd, opts...) if err != nil { return nil, err }
pkg/srvconn/conn_nobody.go+23 −0 added@@ -0,0 +1,23 @@ +package srvconn + +import ( + "os/user" + "strconv" + "syscall" + + "github.com/jumpserver/koko/pkg/localcommand" +) + +func BuildNobodyWithOpts(opts ...localcommand.Option) (nobodyOpts []localcommand.Option, err error) { + nobody, err := user.Lookup("nobody") + if err != nil { + return nil, err + } + uid, _ := strconv.Atoi(nobody.Uid) + gid, _ := strconv.Atoi(nobody.Gid) + nobodyOpts = make([]localcommand.Option, 0, len(opts)+1) + nobodyOpts = append(nobodyOpts, opts...) + nobodyCredential := localcommand.WithCmdCredential(&syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}) + nobodyOpts = append(nobodyOpts, nobodyCredential) + return nobodyOpts, nil +}
pkg/srvconn/conn_postgresql.go+7 −1 modified@@ -5,6 +5,7 @@ import ( "os" "strconv" + "github.com/jumpserver/koko/pkg/logger" _ "github.com/lib/pq" "github.com/jumpserver/koko/pkg/localcommand" @@ -61,7 +62,12 @@ func (conn *PostgreSQLConn) Close() error { func startPostgreSQLCommand(opt *sqlOption) (lcmd *localcommand.LocalCommand, err error) { argv := opt.PostgreSQLCommandArgs() //psql 是启动postgresql的客户端 - lcmd, err = localcommand.New("psql", argv, localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + opts, err := BuildNobodyWithOpts(localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + if err != nil { + logger.Errorf("build nobody with opts error: %s", err) + return nil, err + } + lcmd, err = localcommand.New("psql", argv, opts...) if err != nil { return nil, err }
pkg/srvconn/conn_redis.go+7 −1 modified@@ -9,6 +9,7 @@ import ( "time" "github.com/jumpserver/koko/pkg/localcommand" + "github.com/jumpserver/koko/pkg/logger" "github.com/mediocregopher/radix/v3" ) @@ -95,7 +96,12 @@ func (conn *RedisConn) Close() error { func startRedisCommand(opt *sqlOption) (lcmd *localcommand.LocalCommand, err error) { cmd := opt.RedisCommandArgs() - lcmd, err = localcommand.New("redis-cli", cmd, localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + opts, err := BuildNobodyWithOpts(localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + if err != nil { + logger.Errorf("build nobody with opts error: %s", err) + return nil, err + } + lcmd, err = localcommand.New("redis-cli", cmd, opts...) if err != nil { return nil, err }
pkg/srvconn/conn_sqlserver.go+6 −1 modified@@ -72,7 +72,12 @@ func startSQLServerCommand(opt *sqlOption) (lcmd *localcommand.LocalCommand, err func startSQLServerNormalCommand(opt *sqlOption) (lcmd *localcommand.LocalCommand, err error) { //tsql 是启动sqlserver的客户端 - return localcommand.New("tsql", opt.SQLServerCommandArgs()) + opts, err := BuildNobodyWithOpts(localcommand.WithPtyWin(opt.win.Width, opt.win.Height)) + if err != nil { + logger.Errorf("build nobody with opts error: %s", err) + return nil, err + } + return localcommand.New("tsql", opt.SQLServerCommandArgs(), opts...) } func tryManualLoginSQLServerServer(opt *sqlOption, lcmd *localcommand.LocalCommand) (*localcommand.LocalCommand, error) {
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-4r5x-x283-wm96ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-43651ghsaADVISORY
- github.com/jumpserver/jumpserver/security/advisories/GHSA-4r5x-x283-wm96ghsax_refsource_CONFIRMWEB
- github.com/jumpserver/koko/commit/7d80db95d17c8f42bdf50260dfc21dc2bd0452c2ghsaWEB
- github.com/jumpserver/koko/commit/857f8b9e41f0930dc6190a35d8601fffa5e884e7ghsaWEB
- www.sonarsource.com/blog/diving-into-jumpserver-attackers-gateway-to-internal-networks-2-2mitrex_refsource_MISC
News mentions
0No linked articles in our index yet.