Running db-scan with -S flag fails over wp-config files that include PHP directives
When I run db-scan while specifying the path e.g.
wordfence -dvS db-scan /var/www/
I get the following error:
Located WordPress site at /var/www/
Unable to parse WordPress config file at ./wp-config.php : Function b'ini_set' is not defined
Failed to extract database credentials for site at ./
Traceback (most recent call last):
File "/usr/bin/wordfence", line 8, in <module>
sys.exit(main())
^^^^^^
File "/usr/lib/python3/dist-packages/wordfence/cli/cli.py", line 193, in main
exit_code = invoke_cli()
^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/wordfence/cli/cli.py", line 187, in invoke_cli
return exception_handler.process_exception(exception)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/wordfence/cli/cli.py", line 43, in process_exception
raise exception
File "/usr/lib/python3/dist-packages/wordfence/cli/cli.py", line 185, in invoke_cli
return cli.invoke()
^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/wordfence/cli/cli.py", line 178, in invoke
return subcommand.invoke()
^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/wordfence/cli/dbscan/dbscan.py", line 204, in invoke
raise ConfigurationException(
wordfence.cli.exceptions.ConfigurationException: At least one database to scan must be specified
The source of the issue is the presence in wp-config of things like:
- ini_set( 'max_execution_time', 300 );
- @ini_set( 'log_errors', 'Off' );
- set_time_limit(300);
- max_execution_time = 300;
Removing these from the config results in normal operation.
@redbullpeter Thanks for reporting this. Wordfence CLI at present only has limited support for parsing wp-config files and the functions you've encountered are not currently supported. I've moved this issue into a triage milestone so we can look at adding support for this in the future.
For now, we do not recommend relying on parsing the wp-config file when it contains complexity beyond simply defining the required constants. For such scenarios, you can specify the connection information on the command line (see below) or specify a JSON file with the connection info (especially useful if multiple sites are being scanned).
Database Connectivity:
-H, --host The database hostname
(default: localhost)
-P, --port The database port
-u, --user The database user
(default: root)
--password The database password (this option is insecure)
-p, --prompt-for-password Prompt for a database password
--password-env The environment variable name to check for a password
(default: WFCLI_DB_PASSWORD)
-x, --prefix The WordPress database prefix
(default: wp_)
-D, --database-name The MySQL database name
Hi @akenion thanks. We're in a small scale hosting environment and we're not always aware of the specifics of what's in the wp-config. We're trying to tool the db-scan in a flexible way so that we don't need to track logins and passwords.
For now we've resorted to a bash script that extracts the db details from wp-config and runs the db-scan with the required args.
@redbullpeter If you don't have access to the DB credentials outside of the wp-config file, that sounds like a decent workaround until improvements can be made to the PHP parser in Wordfence CLI. If you are scanning multiple databases and can access the database credentials elsewhere, I would suggest using the JSON file though.
I'll provide an update here once this issue is scheduled for a release.
Opened PR #340 to resolve the wp-config parsing failure. It introduces a targeted parser that walks the AST to extract DB constants without executing directives (including @ini_set, set_time_limit, conditional defines, constant() indirection, etc.), plugs it into db-scan, and adds unit coverage for a bunch of simulated wp-config variants. Full test run: venv/bin/python -m unittest discover -s wordfence -t .