Skip to content

Commit

Permalink
Corret the username format: <username>@%, and use SQL injection for C…
Browse files Browse the repository at this point in the history
…reateUser and DropUser.
  • Loading branch information
hobu authored and hobu committed Jun 15, 2020
1 parent 078ea90 commit a29835d
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 26 deletions.
34 changes: 14 additions & 20 deletions pkg/resourcemanager/mysql/mysqluser/mysqluser.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"github.com/Azure/azure-service-operator/api/v1alpha1"
"k8s.io/apimachinery/pkg/runtime"

_ "github.com/go-sql-driver/mysql" //sql drive link
_ "github.com/go-sql-driver/mysql" //mysql drive link
"k8s.io/apimachinery/pkg/types"
)

Expand Down Expand Up @@ -62,7 +62,7 @@ func (s *MySqlUserManager) GetDB(ctx context.Context, resourceGroupName string,
// ConnectToSqlDb connects to the SQL db using the given credentials
func (s *MySqlUserManager) ConnectToSqlDb(ctx context.Context, drivername string, fullserver string, database string, port int, user string, password string) (*sql.DB, error) {

connString := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify", user, password, fullserver, port, database)
connString := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify&interpolateParams=true", user, password, fullserver, port, database)

db, err := sql.Open(drivername, connString)
if err != nil {
Expand All @@ -78,19 +78,19 @@ func (s *MySqlUserManager) ConnectToSqlDb(ctx context.Context, drivername string
}

// GrantUserRoles grants roles to a user for a given database
func (s *MySqlUserManager) GrantUserRoles(ctx context.Context, user string, server string, database string, roles []string, db *sql.DB) error {
func (s *MySqlUserManager) GrantUserRoles(ctx context.Context, user string, database string, roles []string, db *sql.DB) error {
var errorStrings []string
if err := helpers.FindBadChars(user); err != nil {
return fmt.Errorf("Problem found with username: %v", err)
}

for _, role := range roles {
tsql := fmt.Sprintf("GRANT %s ON `%s`.* TO '%s'@'%s'", role, database, user, server)

if err := helpers.FindBadChars(role); err != nil {
return fmt.Errorf("Problem found with role: %v", err)
}

//TODO: how to use SQL injection for grant command, like CreateUser and DropUser
tsql := fmt.Sprintf("GRANT %s ON `%s`.* TO '%s'", role, database, user)
_, err := db.ExecContext(ctx, tsql)
if err != nil {
errorStrings = append(errorStrings, err.Error())
Expand All @@ -104,20 +104,19 @@ func (s *MySqlUserManager) GrantUserRoles(ctx context.Context, user string, serv
}

// CreateUser creates user with secret credentials
func (s *MySqlUserManager) CreateUser(ctx context.Context, server string, secret map[string][]byte, db *sql.DB) (string, error) {
func (s *MySqlUserManager) CreateUser(ctx context.Context, secret map[string][]byte, db *sql.DB) (string, error) {
newUser := string(secret[MSecretUsernameKey])
newPassword := string(secret[MSecretPasswordKey])

// make an effort to prevent sql injection
if err := helpers.FindBadChars(newUser); err != nil {
return "", fmt.Errorf("Problem found with username: %v", err)
}
if err := helpers.FindBadChars(newPassword); err != nil {
return "", fmt.Errorf("Problem found with password: %v", err)
}

tsql := fmt.Sprintf("CREATE USER IF NOT EXISTS '%s'@'%s' IDENTIFIED BY '%s'", newUser, server, newPassword)
_, err := db.ExecContext(ctx, tsql)
tsql := "CREATE USER IF NOT EXISTS ? IDENTIFIED BY ? "
_, err := db.ExecContext(ctx, tsql, newUser, newPassword)

if err != nil {
return newUser, err
Expand All @@ -126,30 +125,26 @@ func (s *MySqlUserManager) CreateUser(ctx context.Context, server string, secret
}

// UserExists checks if db contains user
func (s *MySqlUserManager) UserExists(ctx context.Context, db *sql.DB, username string, server string) (bool, error) {

//tsql := fmt.Sprintf("SELECT * FROM mysql.user WHERE (Host = '%s') and (User = '%s')", server, username)
func (s *MySqlUserManager) UserExists(ctx context.Context, db *sql.DB, username string) (bool, error) {

err := db.QueryRowContext(ctx, "SELECT * FROM mysql.user WHERE (Host = $1) and (User = $2)", server, username)
err := db.QueryRowContext(ctx, "SELECT * FROM mysql.user WHERE User = $1", username)
//err := db.ExecContext(ctx, tsql)

if err != nil {
return false, nil
}
return true, nil

//rows, err := res.RowsAffected()
//return rows > 0, err

}

// DropUser drops a user from db
func (s *MySqlUserManager) DropUser(ctx context.Context, db *sql.DB, user string, server string) error {
tsql := fmt.Sprintf("DROP USER IF EXISTS '%s'@'%s'", user, server)
func (s *MySqlUserManager) DropUser(ctx context.Context, db *sql.DB, user string) error {

if err := helpers.FindBadChars(user); err != nil {
return fmt.Errorf("Problem found with username: %v", err)
}
_, err := db.ExecContext(ctx, tsql)
tsql := "DROP USER IF EXISTS ?"
_, err := db.ExecContext(ctx, tsql, user)
return err
}

Expand Down Expand Up @@ -183,7 +178,6 @@ func (s *MySqlUserManager) GetOrPrepareSecret(ctx context.Context, instance *v1a

secret, err := secretClient.Get(ctx, key)
if err != nil {
// @todo: find out whether this is an error due to non existing key or failed conn
pw := helpers.NewPassword()
return map[string][]byte{
"username": []byte(""),
Expand Down
7 changes: 4 additions & 3 deletions pkg/resourcemanager/mysql/mysqluser/mysqluser_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import (
"github.com/Azure/azure-service-operator/pkg/secrets"
)

//MySQLUser interface provides the functions of mySQLUser
type MySQLUser interface {
GetDB(ctx context.Context, resourceGroupName string, serverName string, databaseName string) (mysql.Database, error)
ConnectToMySqlDb(ctx context.Context, drivername string, server string, dbname string, port int, username string, password string) (*sql.DB, error)
GrantUserRoles(ctx context.Context, user string, server string, database string, roles []string, db *sql.DB) error
GrantUserRoles(ctx context.Context, user string, database string, roles []string, db *sql.DB) error
CreateUser(ctx context.Context, server string, secret map[string][]byte, db *sql.DB) (string, error)
UserExists(ctx context.Context, db *sql.DB, username string, sevrer string) (bool, error)
DropUser(ctx context.Context, db *sql.DB, user string, server string) error
UserExists(ctx context.Context, db *sql.DB, username string) (bool, error)
DropUser(ctx context.Context, db *sql.DB, user string) error
DeleteSecrets(ctx context.Context, instance *v1alpha1.MySQLUser, secretClient secrets.SecretClient) (bool, error)
GetOrPrepareSecret(ctx context.Context, instance *v1alpha1.MySQLUser, secretClient secrets.SecretClient) map[string][]byte

Expand Down
6 changes: 3 additions & 3 deletions pkg/resourcemanager/mysql/mysqluser/mysqluser_reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func (s *MySqlUserManager) Ensure(ctx context.Context, obj runtime.Object, opts
return false, err
}

user, err = s.CreateUser(ctx, string(instance.Spec.Server), DBSecret, db)
user, err = s.CreateUser(ctx, DBSecret, db)
if err != nil {
instance.Status.Message = "failed creating user, err: " + err.Error()
return false, err
Expand All @@ -162,7 +162,7 @@ func (s *MySqlUserManager) Ensure(ctx context.Context, obj runtime.Object, opts
return false, fmt.Errorf("No roles specified for database user")
}

err = s.GrantUserRoles(ctx, user, string(instance.Spec.Server), string(instance.Spec.DbName), instance.Spec.Roles, db)
err = s.GrantUserRoles(ctx, user, string(instance.Spec.DbName), instance.Spec.Roles, db)
if err != nil {
instance.Status.Message = "GrantUserRoles failed"
return false, fmt.Errorf("GrantUserRoles failed")
Expand Down Expand Up @@ -271,7 +271,7 @@ func (s *MySqlUserManager) Delete(ctx context.Context, obj runtime.Object, opts

user := string(userSecret[MSecretUsernameKey])

err = s.DropUser(ctx, db, user, string(instance.Spec.Server))
err = s.DropUser(ctx, db, user)
if err != nil {
instance.Status.Message = fmt.Sprintf("Delete MySqlUser failed with %s", err.Error())
return false, err
Expand Down

0 comments on commit a29835d

Please sign in to comment.