Skip to content

Added CredentialsProvider callback for getting username and password#2097

Merged
vmihailenco merged 1 commit into
redis:masterfrom
jan-bar:master
Jun 4, 2022
Merged

Added CredentialsProvider callback for getting username and password#2097
vmihailenco merged 1 commit into
redis:masterfrom
jan-bar:master

Conversation

@jan-bar

@jan-bar jan-bar commented May 29, 2022

Copy link
Copy Markdown
Contributor

Recently encountered a security problem, the running process was scanned to the redis plaintext username and password.

so I was inspired by CredentialsProvider and added the same method to the redis library.

I use the cheatengine scanner to run the memory password string.

I block the initConn method, and then use cheatengine to scan the memory of the program. After the initConn method is executed, the password in the memory will be delete immediately.

func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
	if cn.Inited {
		return nil
	}
	cn.Inited = true

	username, password := c.opt.Username, c.opt.Password
	if c.opt.CredentialsProvider != nil {
		username, password = c.opt.CredentialsProvider()
		defer fmt.Scanln() // blocking method while testing
	}

	if password == "" &&
		c.opt.DB == 0 &&
		!c.opt.readOnly &&
		c.opt.OnConnect == nil {
		return nil
	}

	connPool := pool.NewSingleConnPool(c.connPool, cn)
	conn := newConn(ctx, c.opt, connPool)

	_, err := conn.Pipelined(ctx, func(pipe Pipeliner) error {
		if password != "" {
			if username != "" {
				pipe.AuthACL(ctx, username, password)
			} else {
				pipe.Auth(ctx, password)
			}
		}

		if c.opt.DB > 0 {
			pipe.Select(ctx, c.opt.DB)
		}

		if c.opt.readOnly {
			pipe.ReadOnly(ctx)
		}

		return nil
	})
	if err != nil {
		return err
	}

	if c.opt.OnConnect != nil {
		return c.opt.OnConnect(ctx, conn)
	}
	return nil
}

Here is my test process.

test.gif

…t username and password will not be stored in the memory, and the username and password will only be generated once when the CredentialsProvider is called. After the method is executed, the username and password strings on the stack will be released.
@vmihailenco vmihailenco merged commit 56a3dbc into redis:master Jun 4, 2022
@vmihailenco

Copy link
Copy Markdown
Collaborator

Thanks

evilaffliction pushed a commit to reactive-go/redis that referenced this pull request Jun 15, 2022
…aintext username and password will not be stored in the memory, and the username and password will only be generated once when the CredentialsProvider is called. After the method is executed, the username and password strings on the stack will be released. (redis#2097)

Co-authored-by: janbar <janbar@163.com>
evilaffliction pushed a commit to reactive-go/redis that referenced this pull request Jun 15, 2022
…aintext username and password will not be stored in the memory, and the username and password will only be generated once when the CredentialsProvider is called. After the method is executed, the username and password strings on the stack will be released. (redis#2097)

Co-authored-by: janbar <janbar@163.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants