# SPDX-License-Identifier: AGPL-3.0-only
# WordPress path scanning: a REFUSED request for a WordPress PHP file
# or a plugin's readme. Real WordPress traffic serves these paths; a
# 404 or 403 on them means the scanner guessed at an installation, or
# at a plugin, that is not there. Translated from CrowdSec's
# http-wordpress-scan, in its instant-ban variant.
#
# Anchored at the END of the path: /wp-content/uploads/x.png does not
# match, /wp-admin/setup-config.php does. The plugin part matches only
# .txt and .md — the readme/changelog files scanners use to fingerprint
# plugin versions.
#
# A 403 counts only WITHOUT a referer: a site whose security plugin
# refuses admin-ajax.php POSTs from logged-out visitors 403s its own
# readers as they browse (seen 2026-08-19: a person on a product page,
# four 403s in ten seconds, banned as a scanner). A scanner sends no
# referer; a browser navigating a site sends its page. A 404 counts as
# before: nothing real is served at a WordPress path that is not there.
parser: wp-scan-paths
log: http
prefilter: "/wp-"
regex: '^(?P<ip>\S+) \S+ \S+ \[(?P<time>[^\]]+)\] "(?P<method>[A-Z]+) (?P<path>[^ "?]*(?i:/wp-[^ "?]*\.php|/wp-content/plugins/[^ "?]*\.(?:txt|md)))(?:\?[^ "]*)? [^"]*" (?:404 \S+ "[^"]*"|403 \S+ "-") '
time_field: time
time_format: nginx
