wp-cli / wp-config-transformer

Programmatically edit a wp-config.php file
MIT License
81 stars 25 forks source link

Placeholder escaping problem with $[0-9] present in values #2

Closed frankiejarrett closed 6 years ago

frankiejarrett commented 6 years ago

When a $ symbol immediately followed by a digit is used inside a value, what stdout reports doesn't match what actually gets put into the wp-config.php file.

I'd consider this an urgent problem for anyone generating random passwords or salts with the potential for a $[0-9] pattern to exist.

$ wp config set DB_PASSWORD '$12345abcde'
Success: Updated the constant 'DB_PASSWORD' in the 'wp-config.php' file with the value '$12345abcde'.
---
/** MySQL database password */
define( 'DB_PASSWORD', '345abcde' );
$ wp config set DB_PASSWORD 'abc$12345de'
Success: Updated the constant 'DB_PASSWORD' in the 'wp-config.php' file with the value 'abc$12345de'.
---
/** MySQL database password */
define( 'DB_PASSWORD', 'abc345de' );

These work fine ($ not immediately followed by a digit)

$ wp config set DB_PASSWORD '$abcde12345'
Success: Updated the constant 'DB_PASSWORD' in the 'wp-config.php' file with the value '$abcde12345'.
---
/** MySQL database password */
define( 'DB_PASSWORD', '$abcde12345' );
$ wp config set DB_PASSWORD '123$abcde45'
Success: Updated the constant 'DB_PASSWORD' in the 'wp-config.php' file with the value '$abcde12345'.
---
/** MySQL database password */
define( 'DB_PASSWORD', '123$abcde45' );
frankiejarrett commented 6 years ago

@schlessera I haven't had a chance to really dig in to root cause yet, so it's unclear whether this is a problem in the transformer or config command itself, but based on what I was experiencing it seemed like the transformer.

danielbachhuber commented 6 years ago

I've been able to reproduce this report.

based on what I was experiencing it seemed like the transformer.

Yes. If the Success: output is correct, which it is, then the problem is within the transformer.

danielbachhuber commented 6 years ago

The culprit is:

$contents = preg_replace( sprintf( '/(?<=^|;|<\?php\s|<\?\s)%s/m', preg_quote( $old_src, '/' ) ), $new_src, $this->wp_config_src );

Specifically, $12345 is interpreted as a placeholder instead of a direct replacement.