Mercurial > gemma
changeset 467:73c7b2d6246e
Used hex-encoded usernames and a stored procedure to decode them to impersonate with the metamorph user.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 22 Aug 2018 17:43:30 +0200 |
parents | e3035621cc52 |
children | ff9dbe14f033 |
files | cmd/gemma/geoserver.go pkg/auth/opendb.go pkg/middleware/modifyquery.go pkg/models/types.go schema/manage_users.sql |
diffstat | 5 files changed, 23 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/cmd/gemma/geoserver.go Wed Aug 22 17:30:12 2018 +0200 +++ b/cmd/gemma/geoserver.go Wed Aug 22 17:43:30 2018 +0200 @@ -21,7 +21,7 @@ ) const ( - startupSQL = `SET ROLE "${user,sys_admin}"` + startupSQL = `SELECT public.setrole("${user}")` closeupSQL = `RESET ROLE` )
--- a/pkg/auth/opendb.go Wed Aug 22 17:30:12 2018 +0200 +++ b/pkg/auth/opendb.go Wed Aug 22 17:43:30 2018 +0200 @@ -2,8 +2,8 @@ import ( "database/sql" + "encoding/hex" "errors" - "strings" "github.com/jackc/pgx" "github.com/jackc/pgx/stdlib" @@ -41,12 +41,7 @@ WHERE oid IN (SELECT oid FROM cte) AND rolname <> current_user AND EXISTS (SELECT 1 FROM users.list_users WHERE username = current_user)` -const InvalidRoleCharacters = `\"':;` - -var ( - ErrInvalidRoleCharacters = errors.New("rolename contains invalid character") - ErrNoMetamorphUser = errors.New("No metamorphic user configured") -) +var ErrNoMetamorphUser = errors.New("No metamorphic user configured") func AllOtherRoles(user, password string) (Roles, error) { db, err := OpenDB(user, password) @@ -73,9 +68,6 @@ } func RunAs(role string, fn func(*sql.DB) error) error { - if strings.Contains(role, InvalidRoleCharacters) { - return ErrInvalidRoleCharacters - } user := config.MetamorphDBUser() if user == "" { return ErrNoMetamorphUser @@ -85,8 +77,10 @@ return nil } defer db.Close() - if _, err := db.Exec(`SET ROLE "` + role + `"`); err != nil { - return err + if _, err = db.Exec( + `SELECT public.setrole($1)`, hex.EncodeToString([]byte(role)), + ); err == nil { + err = fn(db) } - return fn(db) + return err }
--- a/pkg/middleware/modifyquery.go Wed Aug 22 17:30:12 2018 +0200 +++ b/pkg/middleware/modifyquery.go Wed Aug 22 17:43:30 2018 +0200 @@ -1,6 +1,7 @@ package middleware import ( + "encoding/hex" "log" "net/http" "net/url" @@ -81,9 +82,9 @@ parameters.Del("env") session, ok := auth.GetSession(req) - if ok && !strings.ContainsAny(session.User, auth.InvalidRoleCharacters) { + if ok { log.Printf("Injecting user %s\n", session.User) - parameters.Set("env", "user:"+session.User) + parameters.Set("env", "user:"+hex.EncodeToString([]byte(session.User))) } return nil }
--- a/pkg/models/types.go Wed Aug 22 17:30:12 2018 +0200 +++ b/pkg/models/types.go Wed Aug 22 17:43:30 2018 +0200 @@ -6,8 +6,6 @@ "errors" "regexp" "strings" - - "gemma.intevation.de/gemma/pkg/auth" ) type ( @@ -82,8 +80,7 @@ var errNoValidUser = errors.New("Not a valid user") func (u UserName) IsValid() bool { - return u != "" && - !strings.ContainsAny(string(u), auth.InvalidRoleCharacters) + return u != "" } func (u *UserName) UnmarshalJSON(data []byte) error {
--- a/schema/manage_users.sql Wed Aug 22 17:30:12 2018 +0200 +++ b/schema/manage_users.sql Wed Aug 22 17:43:30 2018 +0200 @@ -204,3 +204,14 @@ CREATE OR REPLACE VIEW pw_reset.list_users AS SELECT username, pw, email_address FROM users.list_users; + +-- To set a role from a hex-encoded user name (which is save from SQL injections). +CREATE OR REPLACE FUNCTION public.setrole(role text) RETURNS void +AS $$ +BEGIN + IF role IS NOT NULL AND role <> '' THEN + EXECUTE format('SET ROLE %I', convert_from(decode(role, 'hex'), 'UTF-8')); + END IF; +END; +$$ + LANGUAGE plpgsql;