wordfence / wordfence-cli Goto Github PK
View Code? Open in Web Editor NEWWordfence malware and vulnerability scanner command line utility.
Home Page: https://www.wordfence.com/products/wordfence-cli/
License: GNU General Public License v3.0
Wordfence malware and vulnerability scanner command line utility.
Home Page: https://www.wordfence.com/products/wordfence-cli/
License: GNU General Public License v3.0
This will result in the same output as the existing --version
flag.
Automatically adjust the layout to accommodate resizing the terminal
Add capability for bash auto-complete. Ex. typing "mal" + tab to autocomplete "malware-scan".
Display a blinking cursor at the end of the Scan completed! Press any key to exit.
line to indicate that the scan is complete and the user may provide input.
On MacOS 13.4.1 (c) (22F770820d) I got the error Error: ctypes objects containing pointers cannot be pickled
when I ran the command as follows:
% wordfence scan --output-path /Users/me/wordfence-cli.csv /Users/me/mysite
▓▓▓
▓▓▓▓▓ ▓▓▓▓▓ _ __ __ ____
▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ | | / /___ _________/ / / __/__ ____ ________
▓▓ ▓ ▓▓ | | /| / / __ \/ ___/ __ /_/ /_/ _ \/ __ \/ ___/ _ \
▓▓ ▓▓ ▓▓▓ ▓▓ ▓▓ | |/ |/ / /_/ / / / /_/ /_ __/ __/ / / / /__/ __/
▓▓ ▓ ▓ ▓ ▓▓ |__/|__/\____/_/ \____/ /_/ \___/_/ /_/\___/\___/
▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ____ _ ___
▓▓ ▓▓▓ ▓ ▓▓▓ ▓ ▓▓▓ ▓▓ / ___| | |_ _|
▓▓▓▓▓ ▓ ▓▓▓ ▓ ▓▓▓▓▓ | | | | | |
▓▓ ▓ ▓▓ ▓▓ ▓ ▓▓ | |___| |___ | |
▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ \____|_____|___|
Scanning path: dz-bigblue
Error: ctypes objects containing pointers cannot be pickled
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/spawn.py", line 120, in spawn_main
exitcode = _main(fd, parent_sentinel)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/spawn.py", line 130, in _main
self = reduction.pickle.load(from_parent)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/synchronize.py", line 110, in __setstate__
self._semlock = _multiprocessing.SemLock._rebuild(*state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory
When using the --output-headers
option, the headers are output before each row rather than just once, causing them to be repeated in the output.
Implement automated remediation of infected files
Currently any custom comments added to the wordfence-cli.ini file are overwritten when a wordfence configure
command is invoked. Add the ability to preserve comments in the INI files. May want to consider prompting the user if they want to preserve the comments in the event the comments are no longer relevant with the new configuration.
Update the wording for --help options to the following:
both malware-scan & vuln-scan
vuln-scan
help
displays same options for wordfence
wordfence configure --help
and wordfence version --help
This is specific to our environment, but running a scan fails on symlinks to files within an LXC container. EG:
$ wordfence malware-scan --allow-io-errors --output-format csv --output-path /root/wordfence/malware_scan_$(date +%Y-%m-%d-%H-%M-%S).csv /data/
...
...
Processing file: /data/04/7674/html/wp-content/cache/autoptimize/index.html
Processing file: /data/04/7674/html/wp-content/cache/autoptimize/js/autoptimize_d41d8cd98f00b204e9800998ecf8427e.js
Processing file: /data/04/7674/html/wp-content/cache/autoptimize/js/autoptimize_fallback.js
Processing file: /data/04/7674/html/wp-content/cache/autoptimize/js/index.html
Exception occurred during scanning: An exception occurred in a child process: Directory search of /data/04/7674/html/wp-content failed ([Errno 2] No such file or directory: '/data/04/7674/html/wp-content/db.php')
1 timeout(s) occurred during scan
The error occurs because a user has installed the Query Monitor plugin which symlinks /data/04/7674/html/wp-content/db.php
to its local mount:
ls -alh /data/04/7674/html/wp-content/db.php
lrwxrwxrwx 1 webuser www-data 64 Aug 9 11:27 /data/04/7674/html/wp-content/db.php -> /var/www/html/wp-content/plugins/query-monitor/wp-content/db.php
We're running wordfence-cli from a dedicated node that is just scanning /data/, and it can't find /var/www/html/
because it's not running within the LXC container.
Basically from the wordfence-cli end I was hoping for an option to simply skip files that it can't find (No such file or directory
). Presumably this doesn't count as an IO error and isn't skipped when --allow-io-errors
is used.
Similarly it fails when it comes across strange filenames:
Exception occurred during scanning: An exception occurred in a child process: Directory search of /data/06/8832/html/wp-content/<xmpG:groupName>Grises</xmpG:groupName>
<xmpG:groupType>1</xmpG:groupType>
<xmpG:Colorants>
<rdf:Seq>
ls /data/06/8832/html/wp-content/
'[24-Feb-2021 17:00:19 UTC] PHP Warning: include('
ai1wm-backups
backupwordpress-b09a546349-backups
debug.log
'<div class="wrap advanced-excerpt">'$'\r\n\t''<h2><?php _e( "Advanced Excerpt Options", '\''advanced-excerpt'\'' ); ?><'
'Files placed in this directory are automatically included by WordPress MU.'$'\n''There'\''s no need to activate them on a plugins page.'$'\n''tinymce_982d78a0a085795c3235d1d8a6f787ee.gz'
index.php
mu-pluginsKEEP-16-Nov-2021
'ns#"><rdf:Description rdf:about="" xmlns:xmp="http:'
'# Only allow direct access to specific Web-available files.'$'\n\n''# Apache 2.2'$'\n''<IfModule !mod_authz_core.c>'$'\n\t''Order Deny,Allow'$'\n\t''Deny from all'$'\n''<'
'%PDF-1.5'$'\r''%'$'\342\343\317\323\r\n''404 0 obj'$'\r''<<'
'<?php'$'\n'
'<?php'$'\r\n'
'<?php'$'\r\n\r\n'
'<?php'$'\r\n''class Advanced_Excerpt {'$'\r\n\t''public $options;'$'\r\n\r\n\t'
'<?php'$'\n\n''function ldap_addmenuuser() {'$'\n'' $objCurrUser = wp_get_current_user();'$'\n'' $objUser = wp_cache_get($objCurrUser->id, '\''users'\'');'$'\n\n'' if (function_exists('\''add_submenu_page'\'')) {'$'\n'' '
plugins
'p-settings.php on line 84'$'\n''[21-Sep-2021 15:36:41 UTC] PHP Warning: include('
themes
upgrade
uploads
webtoffee_export
wptouch-data
'<xmpG:groupName>Grises<'
'<xmpG:type>PROCESS<'
'<?xpacket end="w"?>'$'\r\n''endstream'$'\r''endobj'$'\r''403 0 obj'$'\r''<<'
'ype>'$'\n'' <xmpG:red>232<
Obviously that needs resolving and it's not surprising WF couldn't read them. But again we'd like wordfence-cli just to skip (and maybe log an error) rather than halting the scan when it comes across things like this
Print the final status line, such as:
Found 7 matching file(s) after processing 5758 file(s) containing 97970550 byte(s) over 320 second(s)
After the user closes the curses interface so that information is not lost.
Add a new configure
subcommand for users to walk through configuring Wordfence CLI both upon installation and when wanting to setup a new configuration. This will replace the current --configure
option.
The expected user flow is:
wordfence configure
which steps the user through configuring the wordfence-cli.ini file with the standard options including:wordfence
command before configuring Wordfence CLIIn the event a user attempts any wordfence
command without having a working wordfence-cli.ini file, they will be prompted to first complete the configuration. This includes any command that initiates wordfence cli such as:
Ex: User installed Wordfence CLI but has not yet configured it and attempts a command like the following:
$ wordfence vuln-scan /public_html
You must configure Wordfence CLI before it can be used. Would you like to configure Wordfence CLI now? Y/n
wordfence configure
Upon completing the configure subcommand, alert the user of the following (or a similar sentiment) and return the user to the command line:
"Your Wordfence CLI license has successfully been configured. You may now access all of Wordfence CLI's commands. "
In the event of a user inputting wordfence —-help
or simply wordfence
, display the --help options followed by configuration prompt as mentioned above with:
"You must configure Wordfence CLI before it can be used. Would you like to configure Wordfence CLI now? Y/n
wordfence configure
For this release we also need to convert existing wordfence-cli.ini files for current users to the new format that includes a [DEFAULT] global option, [MALWARE-SCAN] (formerly [SCAN]), and [VULN-SCAN] options.
After the user installs/upgrades to version 2.0.1, they will likely next run a wordfence cli command. When any command is input, the user should be prompted to update their configuration. The expected flow is:
wordfence
command,Current license: abcdefgdc4de91f7407da2c0ed4eafb1e160d91b4646d5a8f50f0b1901828d81
Would you like to automatically request a free Wordfence CLI license? [y/n] (default: n):n
Cache directory (current: ~/.cache/wordfence): [user defines or hits enter to skip]
Number of worker processes (8 CPUs available) (current: 4): [user defines or hits enter to skip]
Would you like to keep any custom settings? [Y/n] (default: Y)
This is in the event the user already has a currently configured wordfence-cli.ini file. If not, refer to "Converting current users to new configuration" above.
If a wordfence-cli.ini file already exists and the user inputs wordfence configure
prompt them with:
"An existing configuration file was found at [path]/wordfence-cli.ini, do you want to overwrite it? [y/n] (default: n):"
This manifests most obviously by the fact that the Files Processed
count in the Summary
section does not always match the status line at the end of the scan (see example below).
Files Processed: 25902
Found 25904 matching file(s) after processing 25905 file(s) containing 1796415054 byte(s) over 120 second(s)
This is because progress updates use the same event queue as other events from the scan and once the event is received for the last file processed, None
is pushed to the queue and further events are not processed.
▓▓▓
▓▓▓▓▓ ▓▓▓▓▓ _ __ __ ____
▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ | | / /___ _________/ / / __/__ ____ ________
▓▓ ▓ ▓▓ | | /| / / __ \/ ___/ __ /_/ /_/ _ \/ __ \/ ___/ _ \ ┌────────────────Summary────────────────┐
▓▓ ▓▓ ▓▓▓ ▓▓ ▓▓ | |/ |/ / /_/ / / / /_/ /_ __/ __/ / / / /__/ __/ │Files Processed: 25902│
▓▓ ▓ ▓ ▓ ▓▓ |__/|__/\____/_/ \____/ /_/ \___/_/ /_/\___/\___/ │Bytes Processed: 1787146627│
▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ____ _ ___ │Matches Found: 25901│
▓▓ ▓▓▓ ▓ ▓▓▓ ▓ ▓▓▓ ▓▓ / ___| | |_ _| │Files / Second: 215│
▓▓▓▓▓ ▓ ▓▓▓ ▓ ▓▓▓▓▓ | | | | | | │Bytes / Second: 14879654│
▓▓ ▓ ▓▓ ▓▓ ▓ ▓▓ | |___| |___ | | └───────────────────────────────────────┘
▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ \____|_____|___|
┌───────────────Worker 1────────────────┐ ┌───────────────Worker 2────────────────┐ ┌───────────────Worker 3────────────────┐ ┌───────────────Worker 4────────────────┐
│Files Processed: 2011│ │Files Processed: 2128│ │Files Processed: 2019│ │Files Processed: 2162│
│Bytes Processed: 138316908│ │Bytes Processed: 141969553│ │Bytes Processed: 161071483│ │Bytes Processed: 146067971│
│Matches Found: 2011│ │Matches Found: 2128│ │Matches Found: 2019│ │Matches Found: 2162│
│Files / Second: 16│ │Files / Second: 17│ │Files / Second: 16│ │Files / Second: 18│
│Bytes / Second: 1151616│ │Bytes / Second: 1182028│ │Bytes / Second: 1341069│ │Bytes / Second: 1216151│
└───────────────────────────────────────┘ └───────────────────────────────────────┘ └───────────────────────────────────────┘ └───────────────────────────────────────┘
┌───────────────Worker 5────────────────┐ ┌───────────────Worker 6────────────────┐ ┌───────────────Worker 7────────────────┐ ┌───────────────Worker 8────────────────┐
│Files Processed: 2164│ │Files Processed: 2357│ │Files Processed: 2135│ │Files Processed: 2205│
│Bytes Processed: 158735847│ │Bytes Processed: 142008332│ │Bytes Processed: 147858666│ │Bytes Processed: 141098769│
│Matches Found: 2164│ │Matches Found: 2357│ │Matches Found: 2135│ │Matches Found: 2204│
│Files / Second: 18│ │Files / Second: 19│ │Files / Second: 17│ │Files / Second: 18│
│Bytes / Second: 1321623│ │Bytes / Second: 1182351│ │Bytes / Second: 1231060│ │Bytes / Second: 1174778│
└───────────────────────────────────────┘ └───────────────────────────────────────┘ └───────────────────────────────────────┘ └───────────────────────────────────────┘
┌───────────────Worker 9────────────────┐ ┌───────────────Worker 10───────────────┐ ┌───────────────Worker 11───────────────┐ ┌───────────────Worker 12───────────────┐
│Files Processed: 2033│ │Files Processed: 2351│ │Files Processed: 2084│ │Files Processed: 2253│
│Bytes Processed: 151237803│ │Bytes Processed: 153478712│ │Bytes Processed: 153055736│ │Bytes Processed: 152246847│
│Matches Found: 2033│ │Matches Found: 2351│ │Matches Found: 2084│ │Matches Found: 2253│
│Files / Second: 16│ │Files / Second: 19│ │Files / Second: 17│ │Files / Second: 18│
│Bytes / Second: 1259195│ │Bytes / Second: 1277852│ │Bytes / Second: 1274331│ │Bytes / Second: 1267596│
└───────────────────────────────────────┘ └───────────────────────────────────────┘ └───────────────────────────────────────┘ └───────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│Worker 4 completed │
│File locator process exited │
│Worker 1 completed │
│Worker 5 completed │
│Worker 9 completed │
│Worker 11 completed │
│Worker 2 completed │
│All workers have completed and all results have been processed. │
│Found 25904 matching file(s) after processing 25905 file(s) containing 1796415054 byte(s) over 120 second(s) │
│Scan completed! Press any key to exit. │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
When at least one file is not included in the scan, the log output should include a notice indicating the number of skipped files and how to include these files in a scan.
This was initially part of #72, but also depends on #75, so this is being broken out as a standalone issue.
Per @ewodrich in #72:
Converting current users to new configuration
For this release we also need to convert existing wordfence-cli.ini files for current users to the new format that includes a [DEFAULT] global option, [MALWARE_SCAN] (formerly [SCAN]), and [VULN_SCAN] options.
After the user installs/upgrades to version 2.0.1, they will likely next run a wordfence cli command. When any command is input, the user should be prompted to update their configuration. The expected flow is:
For example:
Current license: abcdefgdc4de91f7407da2c0ed4eafb1e160d91b4646d5a8f50f0b1901828d81
Would you like to automatically request a free Wordfence CLI license? [y/n] (default: n):n
Cache directory (current: ~/.cache/wordfence): [user defines or hits enter to skip]
Number of worker processes (8 CPUs available) (current: 4): [user defines or hits enter to skip]
Would you like to keep any custom settings? [Y/n] (default: Y)
Update the wordfence-cli.ini file with the new formats that includes:
It appears the issue may be due to the symlink pointing above the target directory (rather than the recursive symlink being nested).
To reproduce, first there must be a symlink in the target directory pointing above the target directory (ex. parent-dir -> ..
), and run wordfence scan .
command with or without options.
Example results:
Scanning path: .
/var/www/html/e-vm.com/public_html/wordpress/wp-content/parent-dir/ew-maxfilesize.php
/var/www/html/e-vm.com/public_html/wordpress/wp-content/parent-dir/www/ew-maxfilesize.php
/var/www/html/e-vm.com/public_html/wordpress/wp-content/parent-dir/www/www/ew-maxfilesize.php
/var/www/html/e-vm.com/public_html/wordpress/wp-content/parent-dir/www/www/www/ew-maxfilesize.php
/var/www/html/e-vm.com/public_html/wordpress/wp-content/parent-dir/www/www/www/www/ew-maxfilesize.php
/var/www/html/e-vm.com/public_html/wordpress/wp-content/parent-dir/www/www/www/www/www/ew-maxfilesize.php
/var/www/html/e-vm.com/public_html/wordpress/wp-content/parent-dir/www/www/www/www/www/www/ew-maxfilesize.php
/var/www/html/e-vm.com/public_html/wordpress/wp-content/parent-dir/www/www/www/www/www/www/www/ew-maxfilesize.php
/var/www/html/e-vm.com/public_html/wordpress/wp-content/parent-dir/www/www/www/www/www/www/www/www/ew-maxfilesize.php
In a similar instance, the following error message was returned when using this command as an example: wordfence scan . --include-files-pattern .txt
Error: Directory search of /var/www/html/e-vm.com/public_html/wordpress/wp-content/parent-dir/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www failed ([Errno 40] Too many levels of symbolic links: '/var/www/html/e-vm.com/public_html/wordpress/wp-content/parent-dir/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www/www')
Add an option for 'all' when using the --output-columns
option for both malware-scan
and vuln-scan
subcommands. This allows a user not to have to input each comma delimited column individually.
Additionally, all columns should be the default when not using the human-readable format.
All of the links from README.md
on the PyPI page for WF CLI are broken. May be related to #23.
Currently if an invalid regex is input, an error message of Error: nothing to repeat at position 0
is returned, noted when using both --include-files-pattern and --exclude-files-pattern.
Example:
wordfence scan . --include-files-pattern=*.txt
returns
Error: nothing to repeat at position 0
Change the message to the following, specifying the invalid parameters input by the user for :
Invalid pattern specified: <invalid-pattern>
OSS?
If any key is pressed while the scan is in progress, this will be read when the scan completes as a keypress and will cause the progress interface to terminate without the user being able to see results.
Add an --include-all-files
flag that will cause all files in scanned directories to be scanned regardless of extension. This should be functionally equivalent to using --include-files-pattern=".*"
in the current version.
When explicitly using --read-stdin
option for both malware-scan and vuln-scan, the scan does not complete as expected.
Vuln-scan
Ex. wordfence vuln-scan /www/wordpress --read-stdin
Compare to behavior where read-stdin is the default such as with command ex. wordfence vuln-scan /www/wordpress
. When explicitly using --read-stdin
option, the scan does not resolve and instead forces the user to interrupt and ending in ^CError:
Malware-scan
Ex. wordfence malware-scan /www/wordpress --read-stdin
Compare to behavior where read-stdin is the default such as with command ex. wordfence malware-scan /www/wordpress
. In this case it appears the scan freezes before completing when explicitly using --read-stdin
. The user has to force an interrupt to end the scan.
I have Debian 10.13
wordfence is not working with python 3.8 (all soft is installed with apt from Debian 10 releases, no custom compilations.
[11580] Error loading Python lib '/tmp/_MEIDjZOhM/libpython3.8.so.1.0': dlopen: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /tmp/_MEIDjZOhM/libpython3.8.so.1.0)
With the addition of the vuln-scan
command in #64, it is no longer apparent that the existing scan
command solely scans for malware and not vulnerabilities. It should be renamed to malware-scan
to avoid any ambiguity.
Additionally, if scan
is invoked after this change, it should inform the user that the scan
command has been renamed.
Currently a user can set the number of workers to 0, which appears to run the malware-scan infinitely with 0% CPU usage.
Add a vuln-scan
subcommand to scan WordPress installations for known vulnerabilities.
With the new Voodoo Child release, the automatic license acquisition logic cannot trigger unless the docker container is launched with -it parameter.
Without that parameter, it looks like this:
$ docker run -v /var/www:/var/www wordfence-cli:latest malware-scan /var/www
Wordfence CLI cannot be used until it has been configured. Would you like to configure it now? [y/n] (default: n): Traceback (most recent call last):
File "/venv/bin/wordfence", line 8, in <module>
sys.exit(main())
^^^^^^
File "/venv/lib/python3.11/site-packages/wordfence/cli/cli.py", line 181, in main
exit_code = cli.invoke()
^^^^^^^^^^^^
File "/venv/lib/python3.11/site-packages/wordfence/cli/cli.py", line 163, in invoke
and not configurer.check_config():
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/venv/lib/python3.11/site-packages/wordfence/cli/configurer.py", line 382, in check_config
self.prompt_for_missing_config()
File "/venv/lib/python3.11/site-packages/wordfence/cli/configurer.py", line 366, in prompt_for_missing_config
should_configure = prompt_yes_no(
^^^^^^^^^^^^^^
File "/venv/lib/python3.11/site-packages/wordfence/util/input.py", line 59, in prompt_yes_no
return prompt(
^^^^^^^
File "/venv/lib/python3.11/site-packages/wordfence/util/input.py", line 20, in prompt
response = input(f'{message}{default_message}: ')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
EOFError: EOF when reading a line
And if you launch it with -it parameter, it does successfully get a license, then subsequently exits.
$ docker run -it -v /var/www:/var/www wordfence-cli:latest malware-scan /var/www
▓▓▓
▓▓▓▓▓ ▓▓▓▓▓ _ __ __ ____
▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ | | / /___ _________/ / / __/__ ____ ________
▓▓ ▓ ▓▓ | | /| / / __ \/ ___/ __ /_/ /_/ _ \/ __ \/ ___/ _ \
▓▓ ▓▓ ▓▓▓ ▓▓ ▓▓ | |/ |/ / /_/ / / / /_/ /_ __/ __/ / / / /__/ __/
▓▓ ▓ ▓ ▓ ▓▓ |__/|__/\____/_/ \____/ /_/ \___/_/ /_/\___/\___/
▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ____ _ ___
▓▓ ▓▓▓ ▓ ▓▓▓ ▓ ▓▓▓ ▓▓ / ___| | |_ _|
▓▓▓▓▓ ▓ ▓▓▓ ▓ ▓▓▓▓▓ | | | | | |
▓▓ ▓ ▓▓ ▓▓ ▓ ▓▓ | |___| |___ | |
▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ \____|_____|___|
Wordfence CLI cannot be used until it has been configured. Would you like to configure it now? [y/n] (default: n): y
Would you like to automatically request a free Wordfence CLI license? [y/n] (default: y): y
Your access to and use of Wordfence CLI Free edition is subject to the Wordfence CLI License Terms and Conditions set forth at https://www.wordfence.com/wordfence-cli-license-terms-and-conditions/. By entering "y" and selecting Enter, you agree that you have read and accept the Wordfence CLI License Terms and Conditions. [y/n] (default: n): y
Free Wordfence CLI license obtained successfully: 72a24fde0b99035b6c2dbd3a71d70756b50e72f2d566895496c07b3e071be3eb9d43470c883d31cd5dbd5e49f6d47a77f0627c765681f58af6b57a0586429a1866d39f61c117464bba8aea3d918b70b9e77e404e5cd72dfeed5ed02b526ce8510e746bb0620b3f6ebe03e797f1f3b870
Cache directory (default: ~/.cache/wordfence):
Number of worker processes (8 CPUs available) (default: 1): 4
Config saved to /root/.config/wordfence/wordfence-cli.ini
Wordfence CLI has been successfully configured and is now ready for use.
... leaving behind a trail of crushes hopes and dreams:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
92f8a3e8cbbd wordfence-cli:latest "wordfence malware-s…" 39 seconds ago Exited (0) 17 seconds ago inspiring_robinson
c2d856a01cba wordfence-cli:latest "wordfence malware-s…" 2 minutes ago Exited (1) 2 minutes ago magical_panini
3e592d5a43a4 wordfence-cli:latest "wordfence malware-s…" 16 minutes ago Exited (0) 15 minutes ago exciting_hypatia
be6ef23db6c9 wordfence-cli:latest "wordfence scan --ve…" 18 minutes ago Exited (1) 18 minutes ago stupefied_shamir
d6758307168e wordfence-cli:latest "wordfence scan --ve…" 18 minutes ago Exited (1) 18 minutes ago upbeat_golick
dcb2293d01e4 wordfence-cli:latest "wordfence scan --ve…" 19 minutes ago Exited (1) 18 minutes ago pedantic_sutherland
e3c8278b2e4a wordfence-cli:latest "wordfence malware-s…" 19 minutes ago Exited (0) 19 minutes ago frosty_tu
[...]
Suggested options for fix:
option 1 : When running in docker mode, have it do the scan after acquiring a license
option 2: modify the execution instructions to run interactively
$ docker run -it --entrypoint bash wordfence-cli
root@83e479bb827a:/venv# wordfence malware-scan /var/www
▓▓▓
▓▓▓▓▓ ▓▓▓▓▓ _ __ __ ____
▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ | | / /___ _________/ / / __/__ ____ ________
▓▓ ▓ ▓▓ | | /| / / __ \/ ___/ __ /_/ /_/ _ \/ __ \/ ___/ _ \
▓▓ ▓▓ ▓▓▓ ▓▓ ▓▓ | |/ |/ / /_/ / / / /_/ /_ __/ __/ / / / /__/ __/
▓▓ ▓ ▓ ▓ ▓▓ |__/|__/\____/_/ \____/ /_/ \___/_/ /_/\___/\___/
▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ____ _ ___
▓▓ ▓▓▓ ▓ ▓▓▓ ▓ ▓▓▓ ▓▓ / ___| | |_ _|
▓▓▓▓▓ ▓ ▓▓▓ ▓ ▓▓▓▓▓ | | | | | |
▓▓ ▓ ▓▓ ▓▓ ▓ ▓▓ | |___| |___ | |
▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ \____|_____|___|
Wordfence CLI cannot be used until it has been configured. Would you like to configure it now? [y/n] (default: n): y
Would you like to automatically request a free Wordfence CLI license? [y/n] (default: y): y
Your access to and use of Wordfence CLI Free edition is subject to the Wordfence CLI License Terms and Conditions set forth at https://www.wordfence.com/wordfence-cli-license-terms-and-conditions/. By entering "y" and selecting Enter, you agree that you have read and accept the Wordfence CLI License Terms and Conditions. [y/n] (default: n): y
Free Wordfence CLI license obtained successfully: c558a814dc7d6a6afc907ef6bdaefb0fdc7cfe007e9060ae6605a4716ea19c10773b065ab54732242f50895fcfd3253dc21f6d7bec85058c700782c9b522e4f00948c6443b79000a9a24296052fe48d9a11bc4680848e73c8f9c25ae5abdc43fda975234ac9505b39214a57028a6ab0a
Cache directory (default: ~/.cache/wordfence):
Number of worker processes (8 CPUs available) (default: 1):
Config saved to /root/.config/wordfence/wordfence-cli.ini
Wordfence CLI has been successfully configured and is now ready for use.
root@83e479bb827a:/venv# wordfence malware-scan /var/www
[..great success..]
"We have a number of installation methods to install Wordfence CLI in our installation documentation which we'd"
Should be
"We have a number of installation methods to install Wordfence CLI in our installation documentation which we'd"
Currently, only the last exception is displayed. The parent exceptions are often necessary for debugging issues and including them in the output would be helpful.
Hi all,
Just started testing the wordfence-cli on a server.
Server OS: debian 11.7
Wordfence version: 1.0.1
When I run wordfence scan /var/www
, I see:
Scanning path: /var/www
Error: Directory search failed
If I enable debugging with wordfence scan -d /var/www
, I see several thousand lines printed to the screen as wordfence-cli scans through the subdirectories. Eventually it exits with this message:
Traceback (most recent call last):
File "main.py", line 4, in <module>
File "wordfence/cli/cli.py", line 17, in main
File "wordfence/cli/scan/scan.py", line 295, in main
File "wordfence/cli/scan/scan.py", line 288, in main
File "wordfence/cli/scan/scan.py", line 229, in execute
File "wordfence/scanning/scanner.py", line 654, in scan
File "wordfence/scanning/scanner.py", line 584, in await_results
wordfence.scanning.exceptions.ScanningException: Directory search failed
[3876313] Failed to execute script 'main' due to unhandled exception!
Everytime it fails, it fails while processing a sub-directory within /var/www
, let's call it /var/www/websites/
. If I run wordfence scan -d /var/www/websites
, I see the exact same Traceback as above.
However, if we create a for loop to run wordfence-cli in each subdirectory under /var/www/websites/
, such as with for d in /var/www/webpages/*; do wordfence scan $d; done
, every single scan completes without error.
Any thoughts? Anything else I can provide?
Default installation and configuration fails with errors on SUSE SLES 15:
Errors:
Solution:
End result:
Hello,
We symlink all core files within /wordpress among others and would rather bypass those files. I've looked at the available options, but doesn't seem possible to bypass core/symlinked files. Is it possible to add a new flag to bypass checking for core files, etc? Example error:
Scanning site at /www...
Traceback (most recent call last):
File "/www/wordfence-cli/wordfence/wordpress/site.py", line 58, in _is_core_directory
if file.is_file():
PermissionError: [Errno 13] Permission denied: '/www/wp-load.php'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "wordfence-cli/main.py", line 4, in <module>
cli.main()
File "/www/wordfence-cli/wordfence/cli/cli.py", line 181, in main
exit_code = cli.invoke()
File "/www/wordfence-cli/wordfence/cli/cli.py", line 175, in invoke
return self.process_exception(exception)
File "/www/wordfence-cli/wordfence/cli/cli.py", line 102, in process_exception
raise exception
File "/www/wordfence-cli/wordfence/cli/cli.py", line 171, in invoke
return self.subcommand.invoke()
File "/www/wordfence-cli/wordfence/cli/vulnscan/vulnscan.py", line 216, in invoke
self._scan_site(
File "/www/wordfence-cli/wordfence/cli/vulnscan/vulnscan.py", line 153, in _scan_site
self._scan(
File "/www/wordfence-cli/wordfence/cli/vulnscan/vulnscan.py", line 77, in _scan
site = WordpressSite(
File "/www/wordfence-cli/wordfence/wordpress/site.py", line 49, in __init__
self.core_path = self._locate_core()
File "/www/wordfence-cli/wordfence/wordpress/site.py", line 111, in _locate_core
if self._is_core_directory(self.path):
File "/www/wordfence-cli/wordfence/wordpress/site.py", line 68, in _is_core_directory
raise WordpressException(
wordfence.wordpress.exceptions.WordpressException: Unable to scan directory at /www
Thanks
We'd love to automatically deploy Wordfence CLI to our servers via Ansible. I've found it easy enough to automate the installation step using pip
. But the configuration is trickier, since it requires the interactive step of specifying the number of processors the scanner should be allowed to use.
It would be great is wordfence configure
had arguments to be able to agree to the y/n questions, request a license, and take the default settings for cache directory and number of worker processes.
I'm thinking it would be great to be able to run a command something like this:
wordfence configure --overwrite --request-license --agree-to-terms --workers=1
Or even simpler:
wordfence configure --use-defaults
In any case, the goal would be to be able to run wordfence configure
as a one-liner.
When using the --progress
option, it's possible that the number of workers may require more real estate than the current terminal size provides.
We could either:
Installed wordfence using "pip install wordfence" on a NearlyFreeSpeech shared hosting site. Wordfence installed to /home/private/.local/bin/wordfence.
Command: [username /home/public]$ wordfence vuln-scan ./ -d
Output:
Scanning site at ./...
Located WordPress files at ./
WordPress Core Version: 6.3.2
Traceback (most recent call last):
File "/home/private/.local/bin/wordfence", line 8, in
sys.exit(main())
File "/home/private/.local/lib/python3.10/site-packages/wordfence/cli/cli.py", line 181, in main
exit_code = cli.invoke()
File "/home/private/.local/lib/python3.10/site-packages/wordfence/cli/cli.py", line 175, in invoke
return self.process_exception(exception)
File "/home/private/.local/lib/python3.10/site-packages/wordfence/cli/cli.py", line 102, in process_exception
raise exception
File "/home/private/.local/lib/python3.10/site-packages/wordfence/cli/cli.py", line 171, in invoke
return self.subcommand.invoke()
File "/home/private/.local/lib/python3.10/site-packages/wordfence/cli/vulnscan/vulnscan.py", line 216, in invoke
self._scan_site(
File "/home/private/.local/lib/python3.10/site-packages/wordfence/cli/vulnscan/vulnscan.py", line 153, in _scan_site
self._scan(
File "/home/private/.local/lib/python3.10/site-packages/wordfence/cli/vulnscan/vulnscan.py", line 86, in _scan
self._scan_plugins(site.get_all_plugins(), scanner)
File "/home/private/.local/lib/python3.10/site-packages/wordfence/wordpress/site.py", line 275, in get_all_plugins
plugins = self.get_plugins(mu=True)
File "/home/private/.local/lib/python3.10/site-packages/wordfence/wordpress/site.py", line 254, in get_plugins
for path in self._generate_possible_plugins_paths(mu):
File "/home/private/.local/lib/python3.10/site-packages/wordfence/wordpress/site.py", line 241, in _generate_possible_plugins_paths
configured = self.get_configured_plugins_directory(mu)
File "/home/private/.local/lib/python3.10/site-packages/wordfence/wordpress/site.py", line 233, in get_configured_plugins_directory
return self._extract_string_from_config(
File "/home/private/.local/lib/python3.10/site-packages/wordfence/wordpress/site.py", line 188, in _extract_string_from_config
state = self._get_parsed_config_state()
File "/home/private/.local/lib/python3.10/site-packages/wordfence/wordpress/site.py", line 179, in _get_parsed_config_state
self.config_state = self._parse_config_file()
File "/home/private/.local/lib/python3.10/site-packages/wordfence/wordpress/site.py", line 166, in _parse_config_file
return context.evaluate(
File "/home/private/.local/lib/python3.10/site-packages/wordfence/php/parsing.py", line 875, in evaluate
instruction.evaluate(state)
File "/home/private/.local/lib/python3.10/site-packages/wordfence/php/parsing.py", line 593, in evaluate
new_value = component.evaluate(state)
File "/home/private/.local/lib/python3.10/site-packages/wordfence/php/parsing.py", line 751, in evaluate
arguments = [argument.evaluate(state) for argument in self.arguments]
File "/home/private/.local/lib/python3.10/site-packages/wordfence/php/parsing.py", line 751, in
arguments = [argument.evaluate(state) for argument in self.arguments]
File "/home/private/.local/lib/python3.10/site-packages/wordfence/php/parsing.py", line 603, in evaluate
value = operator.apply(value, new_value)
File "/home/private/.local/lib/python3.10/site-packages/wordfence/php/parsing.py", line 518, in apply
return self.callable(left, right)
File "/home/private/.local/lib/python3.10/site-packages/wordfence/php/parsing.py", line 531, in
lambda left, right: PhpValue(left.type, left.value + right.value)
AttributeError: 'str' object has no attribute 'type'
Same output if I use "wordfence vuln-scan . -d" or "wordfence vuln-scan /home/public/ -d"
Am I doing something wrong? What other info do you need to troubleshoot this error?
I've requested a license key, it's a 224-character string that came in an email from Wordfence.
Downloaded and verified the package for my server with no issues, but when trying to run configuration, and prompted for the license, I just get "License validation failed. Please try again.". I requested a second license key, fails also.
Is there something else that is supposed to be entered at this prompt?
The NocClient
constructor accepts a timeout
parameter with a default value, but this is not currently passed to the underlying requests library when making requests and hence the requests will never time out.
We currently generate too many signatures (one for each package type and one for each checksum file). We should generate a single checksum file for all release assets and sign that file instead. Documentation should also be updated to reflect this.
/etc/wordfence/wordfence-cli.ini
file first, if present~/.config/wordfence/wordfence-cli.ini
, if presentRestructure the help output for Wordfence CLI to be more user friendly.
Messages from fatal errors are written to the progress interface which is then immediately terminated (due to the fatal error). This prevents users from being able to read these messages.
Instead, the progress interface should be terminated first and then the message should be written directly to stdout rather than through curses.
This occurs when running the malware-scan
command with progress output enabled.
Traceback (most recent call last):
File "/home/alex/.local/bin/wordfence", line 8, in <module>
sys.exit(main())
File "/home/alex/.local/lib/python3.8/site-packages/wordfence/cli/cli.py", line 181, in main
exit_code = cli.invoke()
File "/home/alex/.local/lib/python3.8/site-packages/wordfence/cli/cli.py", line 175, in invoke
return self.process_exception(exception)
File "/home/alex/.local/lib/python3.8/site-packages/wordfence/cli/cli.py", line 102, in process_exception
raise exception
File "/home/alex/.local/lib/python3.8/site-packages/wordfence/cli/cli.py", line 171, in invoke
return self.subcommand.invoke()
File "/home/alex/.local/lib/python3.8/site-packages/wordfence/cli/malwarescan/malwarescan.py", line 181, in invoke
self.scanner.scan(
File "/home/alex/.local/lib/python3.8/site-packages/wordfence/scanning/scanner.py", line 791, in scan
worker_pool.await_results(result_processor)
File "/home/alex/.local/lib/python3.8/site-packages/wordfence/scanning/scanner.py", line 721, in await_results
method = getattr(log, event.data['level'].lower())
AttributeError: 'Logger' object has no attribute 'level 15'
Currently, when running the configure
subcommand with an existing configuration file, the user is prompted with:
An existing configuration file was found at /home/esther/.config/wordfence/wordfence-cli.ini, do you want to overwrite it? [y/n] (default: n):
Since the original settings can be retained rather than completely reset, it might be more clear to the user to say change "overwrite" to "update", or something along those lines:
An existing configuration file was found at /home/esther/.config/wordfence/wordfence-cli.ini, do you want to update it? [y/n] (default: n):
The error occurs when running wordfence configure
for a clean install. After accepting the Cache directory defaults, the program exits.
Cache directory (default: ~/.cache/wordfence):
Error: 'str' object has no attribute 'generate_usage'
Found in testing Case #29 with 4 workers present. The Files/Second jumped over 100 briefly and then when dropping back down the '1' remained on the display though the Files/Second was averaging 85 based on the worker's result. This does not happen with -w=3 because the Files/Second remains below 100 or with -w=5 because the Files/Second remains above 100. For testing purposes, this particular issue is challenging to reproduce outside of my test environment since the speed of files/second differs for each test environment.
Currently when encountering file permission errors during a scan, the scanned files trigger a non-fatal error which could result in files being skipped without user's knowledge. For now, change to make IO errors fatal.
Future considerations: add a second window in the --progress output to capture errors if we want to allow the scan to continue. Alternatively consider adding a flag to skip or fail in the event of encountering errors during a scan.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.